Skip to main content

Code reviews rule: Incorrect sharing clauses

Written by David Martin

Incorrect sharing clauses

Why is this an issue?

The sharing clause on a class declaration decides whether sharing rules are taken into account when that class reads or writes data. A class that doesn't enforce sharing can return records that the running user should not be able to see.

This rule only reports classes that actually access data, either through inline SOQL and DML or through Database and Search method calls. Test classes are not reported.

Bypassing sharing is particularly dangerous in:

  • Lightning components and Aura controllers

  • Visualforce controllers

  • REST/SOAP web services

  • Any code that handles user-supplied record IDs

Which declarations are unsafe depends on the API version of the class, taken from the <apiVersion> in its *.cls-meta.xml file.

Before API version 67.0

Omitting the sharing clause means sharing rules are not enforced, so both of these bypass sharing:

  • Classes with no sharing clause at all

  • Classes explicitly marked without sharing

From API version 67.0 onwards

Classes with no sharing clause default to with sharing, so an omitted clause is no longer a problem. Only an explicit declaration bypasses sharing:

  • Classes explicitly marked without sharing

Examples

Example of incorrect code before API version 67.0:

// ApiVersion 66.0
public class AccountController {
@AuraEnabled
public static List<Account> getAccounts() {
return [SELECT Id, Name, Revenue__c FROM Account];
}
}

Example of incorrect code on any API version:

// ApiVersion 67.0
public without sharing class AccountController {
@AuraEnabled
public static List<Account> getAccounts() {
return [SELECT Id, Name, Revenue__c FROM Account];
}
}

Example of correct code, where sharing is enforced explicitly:

public with sharing class AccountController {
@AuraEnabled
public static List<Account> getAccounts() {
return [SELECT Id, Name, Revenue__c FROM Account];
}
}

Example of correct code on API version 67.0 and later:

// ApiVersion 67.0
public class AccountController {
@AuraEnabled
public static List<Account> getAccounts() {
return [SELECT Id, Name, Revenue__c FROM Account];
}
}

How can I fix violations?

An autofix exists for this rule. It adds inherited sharing to classes that have incorrect sharing clauses.

If you chose to not proceed with autofixes and have Apex code that must remain on a version before API version 67.0:

  1. Add with sharing: Use the with sharing keyword to enforce the current user's sharing rules (if using )

  2. Use inherited sharing: For utility classes that should respect the calling context's sharing mode.

  3. Review without sharing usage: If without sharing is required, document why and ensure it's not exposed to user-facing code.

Otherwise:

  1. Upgrade the API version: Raising a class to API version 67.0 or later makes an omitted clause default to with sharing. Test the class first, because code that relied on the old default will start filtering records.

When should I disable this rule?

You may dismiss specific violations for:

  • Batch Apex classes that need system-level access to process all records

  • Trigger handlers where sharing is enforced at a higher level

  • Utility classes with inherited sharing that delegate to the caller's context

Resources

Did this answer your question?