Saturday, July 1, 2017

Dynamic SOQL And SOSL in Visual force Page for search:

<apex:page controller="searchcls">
  <apex:form >
     <apex:pageBlock >
       <apex:pageBlockSection >
       <apex:pageBlockSectionItem >
         <apex:outputLabel > Contact Name</apex:outputLabel>
         <apex:inputText value="{!searchtext}"/>
       </apex:pageBlockSectionItem>
       <apex:commandButton value="Search" action="{!search}"/>
        </apex:pageBlockSection>
     </apex:pageBlock>
     <apex:pageBlock >
       <apex:pageBlockTable value="{!lstcon}" var="c">
          <apex:column value="{!c.lastname}"/>
          <apex:column value="{!c.firstname}"/>
          <apex:column value="{!c.email}"/>
          <apex:column value="{!c.phone}"/>
       </apex:pageBlockTable>
     </apex:pageBlock>
  </apex:form>
</apex:page>
---------
Class:
public with sharing class searchcls {
     
    public String searchtext { get; set; }
    public list<contact> lstcon{get;set;}
    public PageReference search() {
    String tempInput ='\'%' +searchtext+ '%\'';
     lstcon = new list<contact>();
     string qry ='select id,name,lastname,firstname,email,phone from contact where lastname  like'+tempInput +'order by lastname limit 10'; 
     lstcon = database.query(qry);
     system.debug('--------->'+lstcon);
        return null;
    }
}
---------
SOSL: 
<apex:page controller="SOQLSearchcls" tabStyle="account">
  <apex:form >
    <apex:pageBlock >
      <apex:pageBlockSection >
        Search for All Field Values<apex:inputText value="{!searchtext}"/>
        <apex:commandButton value="search" action="{!search}"/>
      </apex:pageBlockSection>
      <apex:pageBlockSection title="Account Details">
      <apex:pageBlockTable value="{!lstacc}" var="a">
        <apex:column value="{!a.name}"/>
         <apex:column value="{!a.accountnumber}"/>
        <apex:column value="{!a.phone}"/>
        <apex:column value="{!a.fax}"/>
        <apex:column value="{!a.type}"/>
        <apex:column value="{!a.industry}"/>
       
      </apex:pageBlockTable>
       </apex:pageBlockSection>
        <apex:pageBlockSection title="Contact Details">
        <apex:pageBlockTable value="{!lstcon}" var="c">
        <apex:column value="{!c.lastname}"/>
         <apex:column value="{!c.firstname}"/>
        
      </apex:pageBlockTable>
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>
-----
Class:

public with sharing class SOQLSearchcls {
    
    public list<account> lstacc{get;set;}
     public list<contact> lstcon{get;set;}

    public String searchtext { get; set; }
    public PageReference search() {
    
     list<list<sobject>> searchlist =[find :searchtext returning account(name,accountnumber,type,phone,fax,industry),contact(lastname,firstname)];
     system.debug('------'+searchlist );
     lstacc = ((list<account>)searchlist[0]);
      lstcon = ((list<contact>)searchlist[1]);

        return null;
    }

}

SOQL Injection in Salesforce?

Suppose you have a search form and instead of typing a valid search parameter, User types something invalid text  and that can make your SOQL query invalid and expose the unexpected result.

This situation occurs when user input is not filtered for escape characters. let's have a pictorial look :






It's a SQL example , but describe the SOQL injection as well in a good manner.
So here you can see that. In the User id field once user puts a invalid parameter and goes to the controller and form a query that  results in a invalid login.

The worst scenario could be if resultant data from a query supposed to be deleted.
 let's have one more quick example for this :

I have a case where I want to delete the Account based on name entered in the input name field on page.
Implementation can be like this :

List<Account> listAccount = Database.query('Select id from Account where Name = \'' + nameField + '\' '); 

delete listAccount;


It works great with a valid value.
 Now it can be worst if value of nameField is provided like :

nameField = \' OR Id != null OR Type != \'


So once the action will be performed, this will be bind-up with the query and resultant query will be like this :
  

List<Account> listAccount = Database.query('Select id from Account where Name = \'\'\' OR ID != null OR Type != \'\' ');

delete  listAccount;


So hopefully , you can see the monster  here. It will delete the entire database for account records.

Salesforce provides escape functions to get rid from SOQL injection. 
Solution can be one of the followings:

  1. Try to use STATIC queries as much as possible. STATIC query has inbuilt escaping.
  2. If dynamic query is needed , then all the search parameters should use escapeSingleQuotes() function.like
    List<Account> listAccount = Database.query('Select id from Account where Name = \'' + String.escapeSingleQuotes(nameField) + '\' ');
String.escapeSingleQuotes method adds the escape character (\) to all single quotation marks in a string that is passed in from a user. The method ensures that all single quotation marks are treated as enclosing strings, instead of database commands.




No comments:

Post a Comment