Force.com ESAPI: A Key to Simplifying Apex Security Compliance!
While fixing security issues for a customer, I came across a very interesting and powerful security API from Salesforce, i.e., Force.com ESAPI. As per the Google code description, this API:
This API seems to have been started by the Salesforce team (don't know the author); it's mentioned on the landing page of Salesforce security by the name Security Coding Library.
Going forward with this post, I am assuming you are comfortable with the guidelines set by Salesforce to get security review cleared for App Exchange. If you are not, in general, it is a good idea for every Apex/Visualforce developer to go through this link for a better idea about Salesforce Security compliance. If you follow these rules from the very beginning, life will be beautiful later on, near release time.
What is Force.com ESAPI?
On a high level, ESAPI provides the following modules; for more details on each, please refer to the getting started guide: http://code.google.com/p/force-dot-com-esapi/wiki/GettingStarted
Input Validation: Validators are available for credit cards, numbers, dates, and HTTP requests.
Output Encoding: Visualforce equivalents of JSENCODE, HTMLENCODE, etc, in Apex.
Access Control for Force.com objects (CRUD/FLS and Sharing):
First, if you want to understand what CRUD/FLS is concerning Salesforce Security requirements, please go through this link: Enforcing CRUD and FLS.
This module is my favorite and does a good job of saving you from writing a lot of Apex code to ensure CRUD/FLS compliance.
This module gives you APIs to do CRUD operations as per CRUD/FLS permissions of logged-in/current USER. This is important because by default apex runs in GOD MODE, i.e., bypassing the CRUD/FLS (even if WITH SHARING is with class declaration). So rather than doing direct insert contacts or update contacts, one can go for:
insertAsUser(sObject[] someObjs, List<String> fieldsToSet)
updateAsUser(Map<ID, sObject> objMap, List<String> fieldsToUpdate)
This module also provides a facility to plug and play sharing behavior; one can set SHARING to either WITH, WITHOUT, or INHERIT for all the CRUD operations. for ex.
Usage: ESAPI.accessController().setSharingMode(SFDCAccessController.SharingMode.WITH);
Similarly, one can set ALL OR NONE behavior for records, i.e., if you are doing a CRUD operation on an Sobject with 10 fields and out of those 10 current users is permitted for only 5, then should the operation be a success or not? Examples :
setOperationMode(SFDCAccessController.OperationMode omode).
ESAPI.accessController().setOperationMode (SFDCAccessController.OperationMode.ALL_OR_NONE).
Some challenges with this project!
This project is making extensive use of Apex describe information, so it's prone to hitting governor limits on some occasions. More details here: http://code.google.com/p/force-dot-com-esapi/issues/detail?id=3
Force.com Community – Let’s take ESAPI to the next level!
Force.com ESAPI is awesome; I love the way it is architected, i.e.
Follows the thumb rule of loose coupling throughout.
Clear contract definition of each sub-component via interfaces and abstract classes.
Awesome Java-style Apex documents that clearly describe the usage of each API.
What’s required next from us (the Force.com community) is to contribute more to this project via:
Blog, tweet, and discuss this project to increase awareness.
Create detailed code samples for various scenarios per module, especially the CRUD/FLS one. Try adding them to the Google Code WIKI or let others know via your blogs.
Joining as a contributor to this project, add various new API’s like upsertAsUser and various other validation routines.
Test, report and fix the issues.
and much more.
References:
Force.com ESAPI - Google Code Archive
Sharing and Record Access Features - Salesforce
Securing Data in Apex Controllers - Salesforce
Let’s Talk
Drop a note below to move forward with the conversation 👇🏻