0

I have a question about Query: SOQL SOSL Injection

this is my code:

public static String getWhereClause(FilterSearch filters){

        String whereClause = '';
        Integer cropsId = filters.CropsId;
        Integer diseaseWeedDraftId = filters.DiseaseWeedDraftId;
        String[] criteria = new List<String>{};
        if (cropsId!=null && cropsId!=0) {
            criteria.add('starfarmer1__crops_id__c = :cropsId');
        }
        if (diseaseWeedDraftId!=null && diseaseWeedDraftId!=0) {
            criteria.add('starfarmer1__disease_weed_draft_id__c = :diseaseWeedDraftId');
        }
        if (criteria.size() > 0) {
            whereClause = 'WHERE ' + String.join(criteria, ' AND ');
        }
        return whereClause;
    }


public static String getDataFiltersQuery(String whereClause) {

        return 'SELECT ExternalId FROM starfarmer1__salesforce_regist_part_custom__x ' + whereClause + ' AND ExternalId > :exId ORDER BY ExternalId ASC LIMIT :limitValueSelect';
}

I received

"This query detects user-controlled input entering the structure of a SOQL query in Apex. Unlike queries sent via the REST/SOAP API, queries in Apex do not enforce CRUD/FLS checks, and therefore letting the user inject their own SOQL code can lead to unauthorized data access. This is even true if the user can only influence fields in WHERE clauses. To fix this vulnerability, make sure that

  1. user-controlled data that is in a quoted context is entered into the query via a bound variable or is otherwise sanitized with String.escapeSingleQuotes().
  2. For data that is not quoted it must be of a safe data type, such as integer or Id. 3) All other user data must be checked by manually performing CRUD/FLS checks or matching against a whitelist. This may be a false positive if you perform the sanitization outside of the detected dataflow or if the fieldtype is only controlled by a privileged account (custom settings)."

How can i fix ' + whereClause + '

Thanks for the help!

2
  • Becuase you're binding variables in the dynamic query there are no dangers of actual injection here (assuming the second method is only called with the output from the first one as an argument). Your query might not work though, because the variables that are used in the dynamic query have to be local variables where Database.query() is executed. May 27, 2021 at 9:59
  • does my answer work for you?
    – ytiq
    May 27, 2021 at 11:59

1 Answer 1

3

The simplest way is to do it like this:

public static String getDataFiltersQuery(String whereClause) {
     
    String query = 'SELECT ExternalId FROM starfarmer1__salesforce_regist_part_custom__x ' + whereClause + ' AND ExternalId > :exId ORDER BY ExternalId ASC LIMIT :limitValueSelect WITH SECURITY_ENFORCED';

    return String.escapeSingleQuotes(query);
}
  

Because if you try to escape only parts of the query (i.e. like WHERE clause) static analyzers usually still give you a warning.

P.S. don't forget that binding variables should be accessible from the place you're running your code in

6
  • Also dont forget about developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… May 27, 2021 at 10:32
  • Yes, thanks a lot :) updated
    – ytiq
    May 27, 2021 at 11:05
  • Escaping the entire query can cause invalid SOQL, though: String.escapeSingleQuotes('SELECT Id FROM Account WHERE Name LIKE \'Donald%\'') will fail. One must learn to recognize when a false positive is present and document it.
    – sfdcfox
    May 27, 2021 at 12:17
  • ye, therefor we use bind variable for LIKE. Do you have maybe any tips on how to handle it better, cos I don't think that you can handle false positives reliably in ci, for example
    – ytiq
    May 27, 2021 at 13:16
  • So, Do you know any tools check for SOQL SOSL Injection? May 28, 2021 at 0:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .