·
Last changedVersion:
This version passed the hardening gate. Hardening applied 13 targeted changes and preserved all other text. Classified findings before hardening: 0. Classified findings closed: 0. Classified findings remaining: 0. Unclassified scanner findings remaining: 0. Review findings closed: 9. Review findings remaining: 1.
None
None
Expand | File | Group | Subtype | Severity | Status |
|---|
No findings available
0 findings
Apply these checks to every Apex class, trigger, and test file you write or review. When reviewing, report findings and propose changes. Edit files only within the scope the user requested, or after the user confirms.
Scan for these patterns before declaring any Apex file acceptable:
Rule: if you see [SELECT or Database.query, insert, update, delete, upsert, merge inside a for loop body — stop and refactor before proceeding.
Every class must declare its sharing intent explicitly. Undeclared sharing runs in the caller's mode when called from another class, but runs without sharing when the class is the entry point of the transaction (for example a UI controller, REST endpoint, or trigger). Treat an undeclared entry point class as a security finding, and prefer inherited sharing over leaving out a declaration for framework and utility classes.
| Declaration | When to use |
|---|---|
| Default for all service, handler, selector, and controller classes |
| Only when the class must run elevated (e.g. system-level logging). Keep the elevated code in a minimal helper class, require a code comment explaining why, still enforce CRUD/FLS where user data is returned, and get the user's confirmation before generating such a class. |
| Framework entry points that should respect the caller's sharing context |
If a class does not have one of these three declarations, when writing code, add it before writing anything else; when reviewing, report it as a finding.
Apex code that reads or writes records on behalf of a user must verify object and field access. The platform does not enforce FLS or CRUD automatically in Apex.
Writes need the same protection. Run DML on behalf of users in user mode (USER_MODE), or remove fields the user cannot create or update before the write, and check that the user can create, update, or delete the object before the matching DML.
Rule: any Apex method callable from a UI component, REST endpoint, or @InvocableMethod must enforce CRUD/FLS. Sharing declarations such as with sharing control record visibility only and do not replace CRUD/FLS checks. Internal service methods called only from trusted contexts may leave out CRUD/FLS checks only with a documented reason in a code comment.
For dynamic SOQL, pass user supplied values only as bind variables and run the query in user mode; escaping quotes is only a fallback. Add a field name to the query string only after it passes the allowlist check, ideally one built from Schema describe results.
Prefer current language features. Each idiom has its own minimum API version, so check the project's source API version before applying one:
| Old pattern | Modern replacement |
|---|---|
|
|
|
|
|
|
|
|
|
|
Every feature must be tested across all three paths. Missing any one of these is a quality failure:
Test.startTest() / Test.stopTest(): startTest gives the code under test a fresh set of governor limits, and stopTest makes queued async work run before your assertions.with sharing unless the trigger requires elevated access. In that case, keep the elevated logic in a minimal helper class with a documented reason.| Pattern | Action |
|---|---|
SOQL inside | Refactor: query before the loop, operate on collections |
DML inside | Refactor: collect mutations, DML once after the loop |
Class missing sharing declaration | Add |
| Remove — auto-escaping enforces XSS prevention |
Empty | Add logging and appropriate re-throw or error handling; log only the exception type, message, and record IDs, and keep field values, personal data, credentials, and full payloads out of logs |
String-concatenated SOQL with user input | Replace with bind variable or whitelist validation |
Test with no assertion | Add a meaningful |
| Upgrade to |
Hardcoded record ID ( | Replace with queried or inserted test record ID |
Get started with chainctlchainctl skill install public/github/salesforce-apex-quality:latest
Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.
skills.cgr.dev/public/github.com/github/skills/salesforce-apex-quality:latest
MIT
HARDENING.md
LICENSE
SKILL.md