+ Start a Discussion
prageethprageeth 

SOQL Injection

Hello All;

I have a dynamic SOQL query which is called as below.

 

public Account[] getAccounts() {
    String userInput = Apexpages.currentPage().getParameters().get('param');
    Account[] accs = database.query('SELECT name FROM Account 
                        WHERE name = \'' + userInput + '\'');
    return accs;
}

 Here I expect a name of an Account as the userInput.

But as I think a SOQL injection can be done in the above case since the user can input something as below as the the 'param'.

param=Account1' OR name<>'xxx

In above case the user gets data of all the accounts instead of what I expected to return.

But as I think If I have used the "with sharing" keyword in my controller class the user still can't see the records which are not permitted for him.

Am I correct or is still there a way(Security hole) for user to view unauthorized data.

Thanks

 

 

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

Two things:

 

1) with sharing will prevent users from viewing any sort of data they're not supposed to; it makes the queries sharing-sensitive.

2) A better idea is to use a bind variable, which automatically escapes your user input such that they can not enter a SOQL "hack". Ex:

 

 

String userinput = Apexpages.currentPage().getParameters().get('param');
Account[] accs = Database.query('select name from account where name = :userinput');

Bind variables can be used in strings in place of filter values (but not field names or objects). Just precede the variable name with a colon (as in the example above).

 

All Answers

sfdcfoxsfdcfox

Two things:

 

1) with sharing will prevent users from viewing any sort of data they're not supposed to; it makes the queries sharing-sensitive.

2) A better idea is to use a bind variable, which automatically escapes your user input such that they can not enter a SOQL "hack". Ex:

 

 

String userinput = Apexpages.currentPage().getParameters().get('param');
Account[] accs = Database.query('select name from account where name = :userinput');

Bind variables can be used in strings in place of filter values (but not field names or objects). Just precede the variable name with a colon (as in the example above).

 

This was selected as the best answer
ipsita.biswas@in.v2solutions.comipsita.biswas@in.v2solutions.com

Hi Prageeth,

I think the value in your String variable(userInput ) is null which is causing this problem.

 

prageethprageeth

Hey, Thanks