Peter TEMPFLI
3 min readSep 16, 2019

--

Fixing the CRUD/FLS permission violation security issue for Salesforce quickly

No doubts, the CRUD/FLS (data leak) is the number one problem, when you send your new shiny Salesforce app to a security review. If you have no idea, what is it about, have a look on this excellent trailhead module: data leak prevention

TLDR: VisualForce and standard Salesforce enforces permissions on data read/write, both on object and field level. However, APEX runs in ‘system context’, so it has access to every record. A poorly designed Apex controller (or a trigger) can expose date to user which they should not touch!

So, ideally before every DML operation, (as well before SOQL queries) you need to check, if the current user has permission to these objects/fields.

How to do that? Not a big deal. If you want to delete an Opportunity record, you need to do the following:

if (Opportunity.SObjectType.getDescribe().isDeletable() == true) {
delete myOpportunity;
} else {
....blabla....
}

In the same fashion, when you want to update an Opportunity record, you want to make sure the fields which you updating are accessible by the current user:

if (Schema.sObjectType.Opportunity.fields.StageName.isUpdateable()){
update myOpportunity;
} else {
...do something else ...
}

This is easy, but can be very boring with a large codebase. Here’s my solution.

You probably already know the UnitOfWork pattern/framework. I really suggest to outsource every DML operation into it.

The framework itself (in it’s current version) doesn’t do CRUD/FLS check, but is has a very smart feature. When you initialize your UnitOfWork class, you have an option to override the default simpleDMLclass with your own.

The SimpleDML class is super simple — it’s the most basic implementation of the IDML interface.

I already mentioned that I’ve centralized all my DML operations into the UnitOfWork class; so the only thing to do in order to enforce CRUD/FLS check to give it my own IDML implementation. Here’s how I’ve made it:

So, as you see, it’s a different implementation. Before every DML operation, it checks all the CRUD and FLS access rights for the given user.

In order to use it, when I initialize my UnitOfWork class, I’m adding it to as a parameter.

fflib_SObjectUnitOfWork uow = new fflib_SObjectUnitOfWork(
new SObjectType[]{Account.SObjectType},
new doWorkCRUDEnforce()
);

The authors of the UnitOfWork were very smart, so there is no need to modify the fflib_SObjectUnitOfWork class itself — and I still can change its behavior with DML operations.

Sum it up

  • CRUD/FLS access is a big security issue
  • Its easy to fix
  • Just centralize all your DML operations
  • If you use UnitOfWork, use your own implementation of DML operations
  • It is doable with your own implementation of IDML interface

And your app will pass the security review ;)

--

--