Wednesday, February 27, 2013

SOQL Injection

Hi friends, 

While writing dynamic SOQL query, I came to know that we should care about the injection script. I tried to get the way how one can write this kind of script so code starts giving unexpected result. I did a lot of rnd on internet but I found the same sample everywhere which is given in salesforce pdf file, but still I was not getting the practical example that satisfy my SOQL injection doubt. 

Because of this reason I created a sample to clear my self what is SOQL injection & how this can give you unexpected result. Here I am sharing it with you so you will get an idea what does SOQL injection means.

You can see demo here. There are four buttons in this page. these are quite simple & self explanatory but let me explain in detail if you have any doubt-
Button -1 Execute
This button shows how simple dynamic query works if we use Equal comparison

Button -2 Execute Like
This button shows how simple dynamic query works if we use LIKE comparison

Button -3 Execute Escape
This button show how dynamic query works if we use String.escapeSingleQuotes method in case of equal comparison

Button -4 Execute Like Escape
This button show how dynamic query works if we use String.escapeSingleQuotes method in case of LIKE comparison

salesforce recommend to use String.escapeSingleQuotes method if you are writing dynamic query.

Now If you open this page & enter the text just after the button "Account1' OR name<>'abc" & click on all four buttons & see the output difference. 

In the first two buttons we are not using escapeSingleQuotes while in the last two buttons we are using escapeSingleQuotes method. 

here when we give injection script (Account1' OR name<>'abc) first two button show all account in the system, that should not be. while in the last two buttons because we are using escapeSingleQuotes method that does not allow to execute this injection script.

here is the code of page & class-
SOQL.page

<apex:page controller="SOQLController" tabStyle="Account">
 <apex:form id="form1">
  <apex:pageBlock id="block1">
    <apex:inputText value="{!name}" />
    <apex:commandButton value="Execute" action="{!Execute}" rerender="pnl" />
    <apex:commandButton value="Execute Like" action="{!ExecuteLike}" rerender="pnl" />  
    <apex:commandButton value="Execute Escape" action="{!ExecuteEscape}" rerender="pnl" />
    <apex:commandButton value="Execute Like Escape" action="{!ExecuteLikeEscape}" rerender="pnl" /> <apex:outputLabel value="Account1' OR name<>'abc"></apex:outputLabel>
    <apex:outputPanel id="pnl">
    <apex:pageBlockTable value="{!lstAccount}" var="lst" id="tbl">
     <apex:column value="{!lst.Name}" /> 
    </apex:pageBlockTable>
    <apex:pageBlockSection title="Query" columns="1">
     <apex:outputLabel value="{!query}"  id="qry"/>
    </apex:pageBlockSection> 
   </apex:outputPanel> 
  </apex:pageBlock>
 </apex:form>
</apex:page>

& class code.. SOQLController.cls
public with sharing class SOQLController {
 public List<Account> lstAccount{get;set;}
 public string query {get;set;}
 public String name {get;set;}
 public void Execute(){
  String StrName =   '=\'' + name + '\''; 
  query = 'Select Id, Name from Account where name '  + StrName ;
  lstAccount = Database.Query(query);
  //input -- Account1' OR name<>'xxx
 }
 public void ExecuteLike(){
  String StrName =  'LIKE \'%' + name + '%\''; 
  query = 'Select Id, Name from Account where name '+ StrName;
  lstAccount = Database.Query(query);
 }
 public void ExecuteEscape(){
  String StrName =   '=\'' + String.escapeSingleQuotes(name) + '\''; 
  query = 'Select Id, Name from Account where name  '  + StrName;
  lstAccount = Database.Query(query);
 }
 public void ExecuteLikeEscape(){
  String StrName =  'LIKE \'%' + String.escapeSingleQuotes(name) + '%\''; 
  query = 'Select Id, Name from Account where name '  + StrName ;
  lstAccount = Database.Query(query);
 }
}
 

No comments:

Post a Comment