.cursor/skills/security-scan/SKILL.md
Use when scanning Salesforce org Claude Code configuration for security vulnerabilities, deploy misconfigurations, and injection risks in CLAUDE.md, hooks, and MCP servers. Do NOT use for Apex code review — use sf-security.
npx skillsauth add jiten-singh-shahi/salesforce-claude-code security-scanInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
External tool: AgentShield is published as
ecc-agentshieldon npm by affaan-m. It is a third-party security scanner, not part of SCC itself. Maintenance risk: This package has no SLA or maintenance guarantee. If it becomes unavailable, use the manual scanning section below as a fallback.
Audit your Claude Code configuration for security issues using AgentShield.
| File | Checks |
|------|--------|
| CLAUDE.md | Hardcoded secrets, auto-run instructions, prompt injection patterns |
| settings.json | Overly permissive allow lists, missing deny lists, dangerous bypass flags |
| mcp.json | Risky MCP servers, hardcoded env secrets, npx supply chain risks |
| hooks/ | Command injection via interpolation, data exfiltration, silent error suppression |
| agents/*.md | Unrestricted tool access, prompt injection surface, missing model specs |
Beyond configuration scanning, watch for these Salesforce vulnerability patterns:
// VULNERABLE — user input concatenated into query
String query = 'SELECT Id FROM Account WHERE Name = \'' + userInput + '\'';
// SAFE — bind variables
List<Account> results = [SELECT Id FROM Account WHERE Name = :userInput];
// SAFE — Database.queryWithBinds for dynamic SOQL
Map<String, Object> binds = new Map<String, Object>{ 'userInput' => userInput };
List<Account> results = Database.queryWithBinds(
'SELECT Id FROM Account WHERE Name = :userInput',
binds, AccessLevel.USER_MODE
);
| Pattern | Risk | Fix |
|---------|------|-----|
| SOQL without WITH USER_MODE | Reads fields user can't see | Add WITH USER_MODE |
| Database.insert(records) without AccessLevel | Skips FLS on write | Use AccessLevel.USER_MODE |
| WITH SECURITY_ENFORCED | Throws on inaccessible fields, no sharing enforcement | Prefer WITH USER_MODE |
without sharing on class with @AuraEnabled methods — privilege escalationwithout sharing on class with @RemoteAction — same risk via Visualforce{!userInput} without JSENCODE, HTMLENCODE, or URLENCODElwc:dom="manual" with innerHTML from user data$A.util.isEmpty() doesn't sanitize — validate before DOM insertion# Install and scan
npm install -g ecc-agentshield
npx ecc-agentshield scan
# With severity filter and JSON output for CI
npx ecc-agentshield scan --min-severity medium --format json
# Auto-fix safe issues
npx ecc-agentshield scan --fix
| Grade | Score | Meaning | |-------|-------|---------| | A | 90-100 | Secure configuration | | B | 75-89 | Minor issues | | C | 60-74 | Needs attention | | D | 40-59 | Significant risks | | F | 0-39 | Critical vulnerabilities |
# SOQL Injection — string concatenation in queries
grep -rn "Database.query" force-app/ --include="*.cls" | grep -v "bind"
# Missing sharing declaration
grep -rEL "with sharing|without sharing|inherited sharing" force-app/main/default/classes/*.cls
# Hardcoded Salesforce IDs (15 or 18 char)
grep -rnE "'00[0-9a-zA-Z]{12,15}'" force-app/ --include="*.cls"
# Missing CRUD/FLS on DML
grep -rn "insert \|update \|delete \|upsert " force-app/ --include="*.cls" | grep -v "stripInaccessible\|USER_MODE\|SECURITY_ENFORCED\|isAccessible\|@IsTest"
# Hardcoded endpoints
grep -rn "https://\|http://" force-app/ --include="*.cls" | grep -v "Named\|test\|mock\|example.com"
# Full PMD scan
sf code-analyzer run --target force-app --format table
# Security-focused scan
sf code-analyzer run --target force-app --category "Security" --format table
| Finding | Vulnerable Code | Fixed Code |
|---------|----------------|------------|
| SOQL Injection | Database.query('...WHERE Name=\'' + name + '\'') | [SELECT Id FROM Account WHERE Name = :name] |
| Missing Sharing | public class MyService { | public with sharing class MyService { |
| FLS Bypass | insert records; | Database.insert(records, AccessLevel.USER_MODE); |
| Hardcoded ID | '012000000000ABC' | Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Customer').getRecordTypeId() |
| XSS (VF) | {!userInput} | {!HTMLENCODE(userInput)} |
development
Update Salesforce platform reference docs with latest release features and deprecation announcements. Use when SessionStart hook warns docs are outdated or a new Salesforce release has shipped. Do NOT use for Apex or LWC development.
development
Use when syncing documentation after Salesforce Apex code changes. Update README, API docs, and deploy metadata references to match the current org codebase.
development
Use when managing context during long Salesforce Apex development sessions. Suggests manual compaction at logical intervals to preserve deploy and org context across phases.
tools
Visualforce development — pages, controllers, extensions, ViewState, JS Remoting, LWC migration. Use when maintaining VF pages, building PDFs, or planning VF-to-LWC migration. Do NOT use for LWC, Aura, or Flow.