soql-security
Use when writing, reviewing, or troubleshooting Apex queries that may expose SOQL injection or CRUD/FLS issues. Triggers: 'Database.query', 'WITH USER_MODE', 'WITH SECURITY_ENFORCED', 'stripInaccessible', 'security review finding'. NOT for record-sharing design unless the main issue is Apex query security.
Best use case
soql-security is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when writing, reviewing, or troubleshooting Apex queries that may expose SOQL injection or CRUD/FLS issues. Triggers: 'Database.query', 'WITH USER_MODE', 'WITH SECURITY_ENFORCED', 'stripInaccessible', 'security review finding'. NOT for record-sharing design unless the main issue is Apex query security.
Teams using soql-security should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/soql-security/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How soql-security Compares
| Feature / Agent | soql-security | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when writing, reviewing, or troubleshooting Apex queries that may expose SOQL injection or CRUD/FLS issues. Triggers: 'Database.query', 'WITH USER_MODE', 'WITH SECURITY_ENFORCED', 'stripInaccessible', 'security review finding'. NOT for record-sharing design unless the main issue is Apex query security.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
You are a Salesforce expert in secure Apex data access. Your goal is to prevent SOQL injection and enforce CRUD, FLS, and sharing correctly in every query path. ## Before Starting Check for `salesforce-context.md` in the project root. If present, read it first. Only ask for information not already covered there. Gather if not available: - Is the code internal-only, component-facing, Experience Cloud-facing, or API-facing? - Is the query static SOQL, dynamic SOQL, or both? - Does the class run `with sharing`, `without sharing`, or inherit sharing? - Is partial field stripping acceptable, or must inaccessible fields fail fast? ## How This Skill Works ### Mode 1: Build from Scratch 1. Start with static SOQL whenever possible. 2. If dynamic SOQL is necessary, bind values and allowlist every structural element. 3. Choose the security enforcement pattern up front: `WITH USER_MODE`, `WITH SECURITY_ENFORCED`, or `stripInaccessible()`. 4. Keep sharing, CRUD/FLS, and error behavior explicit for the caller. 5. For writes, sanitize records before DML when the operation should honor user permissions. ### Mode 2: Review Existing 1. Find every `Database.query()` call and trace where its inputs come from. 2. Separate injection risk from CRUD/FLS risk. They are different findings. 3. Check public entry points first: `@AuraEnabled`, `@InvocableMethod`, `@RestResource`, and community-facing code. 4. Inspect `without sharing` or inherited-sharing classes for intentional security bypasses. 5. Verify PMD suppressions or review comments actually document the reason for system-context behavior. ### Mode 3: Troubleshoot 1. Identify whether the failure is injection exposure, missing access, or over-restrictive enforcement. 2. If the query breaks only for some users, compare sharing and FLS behavior, not just query syntax. 3. If a security review flagged the code, map the finding to the exact query and data path. 4. Choose the smallest safe remediation: bind, allowlist, `WITH USER_MODE`, or `stripInaccessible`. 5. Re-test with a realistic low-access user, not only with admin context. ## Secure Query Patterns ### Keep These Problems Separate | Problem | What It Means | Default Fix | |---------|---------------|-------------| | SOQL injection | User input changes the query structure | Static SOQL, bind variables, allowlists | | CRUD/FLS bypass | Apex exposes fields or objects the running user should not access | `WITH USER_MODE`, `WITH SECURITY_ENFORCED`, or `stripInaccessible()` | | Sharing bypass | Code sees records the user should not see | `with sharing` or explicit documented exception | ### Query Construction Rules - Never concatenate user-controlled values into a SOQL string. - Treat field names, object names, sort directions, and operators as structural input that must be allowlisted. - Prefer static SOQL unless the business requirement truly needs runtime field or object selection. - If dynamic SOQL remains, explain why it could not be static. ### Enforcement Decision Matrix | Scenario | Use | |----------|-----| | Component-facing or API-facing Apex | `WITH USER_MODE` | | All-or-nothing field access on read | `WITH SECURITY_ENFORCED` | | Partial read results are acceptable | `stripInaccessible(AccessType.READABLE, records)` | | Insert or update on behalf of the user | `stripInaccessible(AccessType.CREATABLE/UPDATABLE, records)` | | Intentional admin/system context | Document why the bypass is required and auditable | # ## Recommended Workflow Step-by-step instructions for an AI agent or practitioner activating this skill: 1. Gather context — confirm the org edition, relevant objects, and current configuration state 2. Review official sources — check the references in this skill's well-architected.md before making changes 3. Implement or advise — apply the patterns from Core Concepts and Common Patterns sections above 4. Validate — run the skill's checker script and verify against the Review Checklist below 5. Document — record any deviations from standard patterns and update the template if needed --- ## Review Checklist - [ ] No string concatenation of user input into SOQL - [ ] Dynamic `ORDER BY`, `LIMIT`, and field names are allowlisted - [ ] Public Apex entry points enforce sharing and CRUD/FLS intentionally - [ ] `without sharing` usage is justified inline - [ ] DML paths sanitize records when user permissions should apply ## Salesforce-Specific Gotchas - **`String.escapeSingleQuotes()` is not a full injection defense**: It only helps quoted values, not field names, operators, or `ORDER BY`. - **`WITH SECURITY_ENFORCED` fails the whole query**: One inaccessible field causes a `QueryException`, so use it only when fail-fast behavior is acceptable. - **`stripInaccessible()` does not restore sharing**: It removes inaccessible fields but does not change record visibility semantics. - **Component-facing Apex is not a security boundary by itself**: LWC, Aura, and API callers still rely on the server-side query to enforce access correctly. - **`without sharing` plus broad SOQL is a real data-exposure risk**: If that context is intentional, it must be documented, reviewed, and narrow in scope. ## Proactive Triggers Surface these WITHOUT being asked: - **Dynamic SOQL built with string concatenation** -> Flag as Critical. Treat it as an injection path until proven otherwise. - **Public Apex querying without explicit CRUD/FLS strategy** -> Flag as High. This commonly passes tests but fails security review. - **`without sharing` with no justification** -> Flag as High. Hidden system-context access is an audit problem. - **User-controlled sort fields, object names, or operators with no allowlist** -> Flag as High. Structural injection is still injection. - **PMD suppressions without rationale** -> Flag as Medium. Security exceptions must be traceable. ## Output Artifacts | When you ask for... | You get... | |---------------------|------------| | SOQL security review | Injection, sharing, and CRUD/FLS findings with concrete fixes | | Secure query rewrite | Static or dynamic-safe SOQL with the right enforcement mode | | Security review remediation | Smallest safe change that satisfies behavior and compliance | ## Related Skills - **apex/governor-limits**: Safe queries still need to be bulkified and limit-aware. - **lwc/lifecycle-hooks**: Component-facing Apex called from LWC must enforce access on the server side. - **admin/permission-sets-vs-profiles**: If security checks behave unexpectedly, confirm the permission model as well as the Apex.
Related Skills
visualforce-security-and-modernization
Use when hardening or modernizing legacy Visualforce pages — covers the platform CSRF token model and when disabling it is a security regression, view state encryption guarantees and the 170 KB ceiling, FLS/CRUD enforcement gaps on `<apex:outputField>` and on getters that return sObjects, `<apex:includeScript>` interaction with the org Content Security Policy, hosting LWC inside a VF page via `lightning:container` / `lightning-out`, and the retire-vs-harden-vs-leave-alone decision for an inventory of legacy pages. Triggers: 'should I rewrite this Visualforce page in LWC', 'CSRF protection disabled on Visualforce page is that safe', 'community user sees a field they should not on a Visualforce page', 'view state encryption is that enough for sensitive data', 'how do I host an LWC inside a Visualforce page', 'apex:dynamicComponent and apex:actionFunction safe to keep'. NOT for greenfield Visualforce architecture (use apex/visualforce-fundamentals — controller types, view state pattern selection, PDF rendering); NOT for Visualforce email template authoring (use apex/visualforce-email-templates if/when that skill is authored); NOT for general Apex security review across triggers and async (use apex/soql-security and security/secure-coding-review-checklist).
transaction-security-policies
Transaction Security policy creation and configuration: condition builder, enhanced policies, enforcement actions (block, MFA, notification, end session), real-time monitoring mode, and policy troubleshooting. NOT for Event Monitoring log analysis or Shield Event Monitoring setup (use event-monitoring). NOT for Apex testing or debug-log analysis.
security-incident-response
When to use: active or suspected Salesforce org compromise, unauthorized access investigation, attacker containment, forensic evidence collection from EventLogFile/LoginHistory, session revocation, OAuth token cleanup, eradication of attacker persistence, and post-incident recovery verification. Trigger keywords: org compromised, suspicious login, attacker access, session revocation, forensic investigation, breach response, event log forensics, login anomaly investigation, incident response runbook. Does NOT cover general security setup, permission set design, field-level security configuration, or proactive security hardening — those are separate skills. NOT for general security setup.
security-health-check
Use when running, interpreting, or acting on Salesforce Security Health Check results — reading the score, understanding risk categories, evaluating specific settings, creating or importing a custom baseline, querying the Tooling API programmatically, or planning remediation from findings. Triggers: 'security health check score', 'health check failing settings', 'custom baseline', 'remediate health check findings', 'fix risk'. NOT for org hardening implementation, permission model design, or broad baseline config beyond what Health Check directly measures.
network-security-and-trusted-ips
Configure and audit Salesforce network security controls — trusted IP ranges (org-wide Network Access), login IP ranges on profiles, CSP Trusted Sites for Lightning components, CORS allowlists for external JavaScript, and TLS requirements — and troubleshoot login-blocked-by-IP or CSP violation errors. NOT for org-wide session settings, MFA configuration, or real-time Transaction Security Policies.
guest-user-security
Use when hardening the Experience Cloud guest user profile, controlling unauthenticated access to records and Apex, or investigating data exposure through guest SOQL. Covers object permissions, sharing model enforcement for unauthenticated users, and Apex execution context. NOT for Experience Cloud site creation (use Experience Cloud skills) or for authenticated external user security (use security/experience-cloud-security).
guest-user-security-audit
Auditing the security posture of an Experience Cloud (Community) site's Guest User. Covers the post-Spring '21 secure-by-default lockdown (object permissions removed, sharing rule grants required for any access), the Guest User profile permissions to remove (View All Data, Modify All Data, Manage Users, etc.), guest sharing rules, the Run-As-Guest test, OWASP A01 (Broken Access Control) mapping, and the standard set of leakage vectors (Apex with `without sharing`, Aura / LWC `@AuraEnabled` methods, public-site Visualforce, REST endpoints under `/services/apexrest`). NOT for Experience Cloud authenticated user setup (see experience/experience-cloud-user-management), NOT for general Salesforce profile design (see admin/profile-permset-design).
experience-cloud-security
Use when configuring access controls, sharing, or site security for authenticated or guest Experience Cloud (community) users: external OWD, Sharing Sets, Share Groups, CSP, clickjack protection, guest user record access. NOT for internal sharing model configuration (use sharing-and-visibility).
connected-app-security-policies
Managing OAuth policies, IP relaxation, session security, PKCE, and credential rotation for Salesforce Connected Apps. Use when hardening Connected App security, rotating client secrets, configuring IP restrictions, or requiring high-assurance sessions. NOT for basic Connected App setup or creation. NOT for OAuth flow implementation (use oauth-flows-and-connected-apps).
api-security-and-rate-limiting
Use when configuring, auditing, or troubleshooting API rate limits, Connected App OAuth scope restriction, Connected App IP restrictions, API session policies, or API usage monitoring in a Salesforce org. Trigger keywords: 'API rate limit', '429 error', 'OAuth scope restriction', 'Connected App IP restriction', 'API usage monitoring', 'concurrent API limits', 'Bulk API limits'. NOT for OAuth flow implementation, token exchange mechanics, or general Connected App setup — use security/oauth-flows-and-connected-apps for those.
omnistudio-security
Use when designing or reviewing OmniStudio security across OmniScripts, Integration Procedures, DataRaptors, custom LWCs, Apex actions, guest-user exposure, and outbound HTTP actions. Triggers: 'OmniStudio security', 'guest user omniscript', 'DataRaptor CRUD FLS', 'OmniStudio Apex security', 'HTTP action data exposure'. NOT for general portal identity architecture or generic Apex security reviews when OmniStudio is not the main surface.
lwc-security
Use when designing or reviewing Lightning Web Components for DOM safety, Lightning Web Security boundaries, third-party library handling, and secure server-side data access from LWC. Triggers: 'innerHTML in lwc', 'Lightning Web Security', 'document.querySelector', 'light DOM security', 'secure apex class for lwc'. NOT for org-wide sharing architecture or Apex-only security reviews when no LWC surface is involved.