Reader small image

You're reading from  Mastering Apex Programming

Product typeBook
Published inNov 2020
Reading LevelIntermediate
PublisherPackt
ISBN-139781800200920
Edition1st Edition
Languages
Right arrow
Author (1)
Paul Battisson
Paul Battisson
author image
Paul Battisson

Paul Battisson is the CEO of Groundwork Apps, a Salesforce ISV Partner, a 9- time Salesforce MVP, and a current MVP Hall of Fame member. He has spoken at numerous Salesforce events including Dreamforce, London's Calling, the Salesforce London World Tour, India Dreamin, and DreamOle. He runs the Leeds Developer Group in the UK and the CloudBites TV website and YouTube channel where he helps Salesforce developers, consultants, admins and architects. He is the author of multiple books and training courses on Salesforce programming.
Read more about Paul Battisson

Right arrow

Chapter 6: Secure Apex Programming

In the previous chapters of this book, we have covered ways in which we can improve our Apex code to ensure that we minimize the number of basic errors we are receiving and also make it easier to handle and deal with them. In this chapter, we are going to finish this first section of the book by discussing how we can make Apex more secure, and ensure that users are not able to perform actions that we do not intend for them.

There are many reasons this is important, but key among them is ensuring that should a user become malicious or their account get compromised, then the damage they can do is limited. I worked with a client that had a faulty website integration design that allowed external users to view all contacts and accounts within the system. Their web developers had noticed this issue and recommended the client get it fixed by a Salesforce consultant (hence, my involvement).

At that time, the client was initially unsure of the severity...

How permissions and sharing work on Salesforce

The Salesforce platform has two main ways of controlling access to records—permissions and sharing. They are often confused for one another but have very different roles in managing access to data. Permissions in Salesforce focus on what you can do with a particular object in general; think of it as akin to a keycard that lets you access different levels of a building.

Sharing focuses on what records you can see for that object based on their ownership. This is like the different rooms our keycard can open on the floors we have access to. If our building was a corporate office block, then as a member of the IT team, we may have access to each floor (permission for each object) and the ability to look at everyone's desk. The CEO may have access to every floor but not into the server room in the basement for security and safety reasons.

With Salesforce's permissions and sharing tools, you can build up a very granular...

Enforcing sharing

Once we have our sharing mechanisms set up within the system, we need to ensure that they are being enforced and followed throughout the application. There is no point restricting visibility of the data within the solution through the administrative tools and then ignore this using the automation setup.

By default, all Apex operations (and Process Builder and certain Flows) run in System Mode; that is, they execute as a generic system user that has access to all metadata and data within the org. This means that although we may have sharing rules and permissions configured to limit access, our code can still act without limitations. For record sharing, this has both positive and negative consequences:

  • On the positive side, it means that our Apex code can retrieve data that the user cannot see to either provide more accurate values (for example, when running an aggregate query) or to retrieve data we wish to utilize in our solution, but not necessarily view...

Sharing records using Apex

Salesforce has several ways of sharing records with users and groups of users such as managed sharing, user-managed (or manual) sharing, and Apex managed sharing:

  • Managed sharing is the point-and-click sharing that most Salesforce developers and administrators are familiar with, and relies upon record ownership, the role hierarchy in the org, and any sharing rules.
  • User-managed sharing or manual sharing is when a user chooses to share a record with a user or group of users using the Share button (currently only in Salesforce Classic).
  • Apex managed sharing is the sharing of records with a user or group of users through the use of Apex code and is what we will be focusing on in this section.

All three of the methods described store records in the share object associated with the record within the Salesforce database. For every object, there is a corresponding share object. For standard objects, it is the object API name plus share,...

Enforcing object and field permissions

As previously mentioned, all Apex runs in System Mode and has access to all metadata and data within the org. This means that regardless of what permissions the user may have on an object or field, Apex can see all objects and fields. This again has some positive and negative consequences:

  • On the positive side, we are now able to ensure that our code can act in ways that our user could not through a standard user interface. For example, we may have a field storing sensitive data that the user should not see or have access to for compliance reasons. Our code can still access this field on behalf of the user to enable it to be used within their workflow. As long as the code is correctly encapsulated and limited in how it is accessed, this is a great way of both enforcing permissions and allowing the desired business process to operate freely.
  • On the negative side, this model means that if we are not careful, then we can accidentally...

Understanding Apex class security

Access to an Apex class can be granted through either a Profile or a Permission Set. For internal users of the platform, it is unlikely that you will ever face major problems with Apex class access, as typically the user is not accessing the Apex class directly, rather accessing it via a user interface, Process Builder, or Flow, which separates them from direct Apex class access.

This is not the case when exposing classes for use as an API, that is, using the webservice keyword or classes annotated by @RestResource. In these situations, the user must be explicitly granted access through the use of a Profile or Permission Set. Note that only the top-level class, that is, the one directly invoked by the end user, must be granted access to it. Any other classes that this top-level class calls through its functions do not need access granted to them.

When defining APIs in Apex, care should be taken to construct the code in a way that firstly verifies...

Enforcing permissions and security within SOQL

When we discussed enforcing sharing rules earlier in this chapter, we noted how the use of the with sharing keywords on a class declaration would ensure that any query run within that class has the sharing rules for the user enforced upon the query. We also saw, in the Enforcing object and field permissions section, how we can work with results returned from a query and enforce permissions on these records using the stripInaccessible method.

In the Spring '20 release, Salesforce added the WITH SECURITY_ENFORCED clause to the SOQL language. Unlike the stripInaccessible method, if the user is lacking permissions for a field, an exception is thrown rather than the field simply being removed.

To apply this clause, we simply include WITH SECURITY_ENFORCED after any WHERE clause and before any ORDER BY, LIMIT, OFFSET, or aggregate function clauses. For example, consider the following:

List<Contact> = [SELECT FirstName, LastName...

Avoiding SOQL injection vulnerabilities

It is a common use case to want to receive some user input and use this as part of a SOQL query filter. However, while this provides helpful user functionality, it can be misused by a malicious user to gain access to additional data that is not meant to be visible to them.

For example, we could be searching for a contact record with the last name in the form of an input string we have defined, as shown in the following code:

public String searchName {get; set;}
public PageReference search() {
	return Database.query('SELECT Id, FirstName, LastName, Email FROM Contact WHERE LastName Like \'%' + searchName + '%\'');
}

In this preceding code, we are defining a dynamic SOQL query where, when the user enters a search term, for example, Smith, the code will then search for contacts where the LastName field is like Smith, effectively running the following query:

SELECT Id, FirstName, LastName, Email FROM Contact...

Summary

In this chapter, we have focused on the many ways in which we can ensure that we are maintaining the security of our application via our Apex code.

Trust has always been Salesforce's number-one value. As an organization, handling hundreds of billions of daily transactions with hundreds of thousands of customer storing their data, they have to make sure that you can be confident that they will not put your data at risk. As a part of that agreement, however, we as developers have to ensure that we are not accidentally exposing data or allowing users to access more data than they should be able to.

We started the chapter by looking at how sharing and permissions are managed on Salesforce before reviewing how we can enforce them within our Apex code, then looking at how we can create and manage custom sharing setups using Apex-managed sharing.

Following this, we moved to the other side of the Salesforce access control model, object, and field permissions. We saw...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering Apex Programming
Published in: Nov 2020Publisher: PacktISBN-13: 9781800200920
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Paul Battisson

Paul Battisson is the CEO of Groundwork Apps, a Salesforce ISV Partner, a 9- time Salesforce MVP, and a current MVP Hall of Fame member. He has spoken at numerous Salesforce events including Dreamforce, London's Calling, the Salesforce London World Tour, India Dreamin, and DreamOle. He runs the Leeds Developer Group in the UK and the CloudBites TV website and YouTube channel where he helps Salesforce developers, consultants, admins and architects. He is the author of multiple books and training courses on Salesforce programming.
Read more about Paul Battisson