3

The CRUD permission check for Security Review has been imposed recently, though I'm clear on the DML statement and Create/Update/Delete permissions I need to check for in my code, but I'm not clear how to proceed with SOQL queries in my code.

Do I need to verify Object read permissions for Objects & all fields in query before executing SOQL?

Consider following code:

public with sharing class MySetupController {

    public MySetupController() {
        system.debug('@ Read Permission Check: '+Schema.myns__Global_Settings__c.getSObjectType().getDescribe().isAccessible());
        myns__Global_Settings__c[] f   = [Select Id From myns__Global_Settings__c limit 1];
        util.logInfo('f: '+f);
        initSettingsRequired            = (f.size() == 0);
    }

}

In this code, the Schema.myns__Global_Settings__c.getSObjectType().getDescribe().isAccessible() is FALSE but still I am able to execute the query just below that line without any error. I don't understand why it didn't threw error and allowed reading the object, I even get 1 record in the next debug statement for that query.

Please note that the current User's profile does not have any CRUD permission on this object myns__Global_Settings__c. I've turned all Object Permission Checkboxes Off in User's Profile.

1 Answer 1

4

You should check that the current user has isAccessible() permission on the fields in the WHERE clause as well as any fields in the SELECT clause being returned to the logged in user. The reason why you need to do this check is that Apex will not throw a DML error when accessing fields that the user cannot access, so it is up to you to enforce the platform's permission model.

There is some confusion if your intuition comes from working in the developer console or via the API. The developer console runs in an execute anonymous context in which permissions are enforced. Permissions are enforced in the API as well. Permissions are not enforced in apex code running in your org, so you as the developer need to enforce them. You will not get permissions exceptions.

Also, be aware of the difference between profile perms, CRUD/FLS perms, and record sharing. Profile perms are always enforced but are only refreshed across logins. CRUD/FLS are never enforced which is why you need to make all those .isAccessible(), and isCreatable() calls before accessing, updating, deleting or inserting records. Record sharing is enforced if your class is 'with sharing'.

In terms of implementation, it's up to you as the dev to enforce programmatically whatever isn't enforced automatically by the platform, where appropriate. In some cases you may want to set a field as private/private for sharing and then ignore sharing when accessing the field. This should only be done for custom fields. In the case of sites and guest user access, you may also need to ignore CRUD/FLS, but again this should only be done for custom fields that are in your namespace. For standard fields you must always enforce CRUD/FLS (no exceptions), and you must always enforce sharing in the entry-points to your app (controllers and global classes). Hide the without sharing code in library functions invoked downstream from your entry points.

4
  • Regarding fields in WHERE clause, looks rather arguable for me. From my perspective, you shouldn't show fields/columns without permissions, but what's going on in WHERE statement that's up to the server side. Sharing would control visibility per record.
    – wesaw
    Commented Oct 19, 2017 at 7:32
  • @wesaw Imagine the following query: SELECT Id FROM Account WHERE CreditCardNo__c LIKE '1%'. Commented Oct 20, 2017 at 2:32
  • Looks more like a not well thought query, which someone is trying to fix with profile access. I'd rather change the query - add param validation, escaping, maybe some business related rules etc.
    – wesaw
    Commented Oct 20, 2017 at 6:08
  • But if I really need query like that, that the point. I could revoke access to CreditCardNo__c, and check only for list of fetched columns against profile. So user would not have access to credit card numbers, but at the same time query would work.
    – wesaw
    Commented Oct 20, 2017 at 6:10

You must log in to answer this question.

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