Use Inherited Sharing to Secure Your Apex Code

You can now specify the inherited sharing keyword on an Apex class, which allows the class to run in the sharing mode of the class that called it. Using inherited sharing enables you to pass security review and ensure that your privileged Apex code is not used in unexpected or insecure ways. An Apex class with inherited sharing runs as with sharing when used as a Visualforce page controller, Apex REST service, or an entry point to an Apex transaction.

Where: This change applies to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions.

Why: Apex without a sharing declaration is insecure by default. Designing Apex classes that can run in either with sharing or without sharing mode at runtime is an advanced technique and can be difficult to distinguish from one where a specific sharing declaration is accidentally omitted. An explicit inherited sharing declaration makes the intent clear, avoiding ambiguity arising from an omitted declaration or false positives from security analysis tooling.

There is a distinct difference between an Apex class that is marked with inherited sharing and one with an omitted sharing declaration. If the class is used as the entry point to an Apex transaction, an omitted sharing declaration runs as without sharing. However, inherited sharing ensures that the default is to run as with sharing. A class declared as inherited sharing runs only as without sharing when explicitly called from an already established without sharing context.

How: This example declares an Apex class with inherited sharing and a Visualforce invocation of that Apex code. Because of the inherited sharing declaration, only contacts for which the running user has sharing access are displayed. If the declaration is omitted, even contacts that the user has no rights to view are displayed due to the insecure default behavior of omitting the declaration.
public inherited sharing class InheritedSharingClass{
    public List<Contact> getAllTheSecrets(){
        return [SELECT Name FROM Contact];
    }
}
<apex:page controller="InheritedSharingClass">
    <apex:repeat value="{!allTheSecrets}" var="record">
        {!record.Name}
    </apex:repeat>
</apex:page>