Skip to content
Language guides Reviewed 2026-09-12

Apex and Salesforce secure coding

Apex services need both safe query construction and explicit data-access decisions. Salesforce Apex called by Lightning components must consider record sharing, object permissions and field-level security separately. SOQL injection prevention does not establish any of those permissions by itself.

Bind values and declare access mode

Assume name is a request-derived string inside an Apex class with an explicit sharing declaration. The snippets return account identifiers for an exact name match.

Unsafe: append the name to dynamic SOQL.

List<Account> accounts = Database.query(
    'SELECT Id FROM Account WHERE Name = \'' + name + '\''
);

Safer: use a static query with a bind and user-mode access.

List<Account> accounts = [
    SELECT Id FROM Account
    WHERE Name = :name
    WITH USER_MODE
];

The bind keeps the name a value instead of SOQL syntax. Explicit WITH USER_MODE also makes the intended data-access mode visible. Check your class API version and platform behavior rather than relying on defaults across versions. Salesforce documents SOQL bind variables and secure Apex access.

Use an explicit sharing declaration appropriate to the calling context. with sharing addresses record-level sharing; it is not a substitute for object and field permissions. Where partial field access should produce a reduced response, review Security.stripInaccessible and handle the result intentionally. Avoid returning raw exception text to the client.

Check the fix

Create fictional accounts in an isolated Salesforce test context, including O'Reilly Demo. The exact-name query should match only that account. Run access tests as a limited user and check both an inaccessible record and a restricted field. A successful administrator test alone does not verify the customer's permissions boundary.

If sort fields or object names must vary, map them to a fixed set of permitted identifiers. Bind variables are not a mechanism for choosing arbitrary query structure. Bound result sizes and avoid exposing data through debug logs.

Continue with SQL and query injection, mass assignment, XSS and open redirects. These examples explain Apex review patterns; enabled scanner rules and platform versions determine the exact checks available for a project.