security-scan

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.

External tool: AgentShield is published as ecc-agentshield on 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.

Security Scan Skill

Audit your Claude Code configuration for security issues using AgentShield.

When to Use

  • Before submitting an AppExchange managed package for security review
  • When running a pre-deployment security gate in CI/CD pipelines
  • When auditing a new codebase for SOQL injection, XSS, or FLS violations
  • When a PMD or Checkmarx scan surfaces violations that need triaging
  • When validating that new Apex contributors follow secure coding patterns

What It Scans

FileChecks
CLAUDE.mdHardcoded secrets, auto-run instructions, prompt injection patterns
settings.jsonOverly permissive allow lists, missing deny lists, dangerous bypass flags
mcp.jsonRisky MCP servers, hardcoded env secrets, npx supply chain risks
hooks/Command injection via interpolation, data exfiltration, silent error suppression
agents/*.mdUnrestricted tool access, prompt injection surface, missing model specs

Salesforce-Specific Security Checks

Beyond configuration scanning, watch for these Salesforce vulnerability patterns:

SOQL Injection

// 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
);

FLS/CRUD Bypass

PatternRiskFix
SOQL without WITH USER_MODEReads fields user can't seeAdd WITH USER_MODE
Database.insert(records) without AccessLevelSkips FLS on writeUse AccessLevel.USER_MODE
WITH SECURITY_ENFORCEDThrows on inaccessible fields, no sharing enforcementPrefer WITH USER_MODE

Sharing Model Violations

  • without sharing on class with @AuraEnabled methods — privilege escalation
  • without sharing on class with @RemoteAction — same risk via Visualforce
  • Missing sharing declaration — inherits calling class context

XSS Patterns

  • Visualforce: {!userInput} without JSENCODE, HTMLENCODE, or URLENCODE
  • LWC: lwc:dom="manual" with innerHTML from user data
  • Aura: $A.util.isEmpty() doesn't sanitize — validate before DOM insertion

Usage

AgentShield Scan

# 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

Severity Levels

GradeScoreMeaning
A90-100Secure configuration
B75-89Minor issues
C60-74Needs attention
D40-59Significant risks
F0-39Critical vulnerabilities

Manual Scanning (Without AgentShield)

# 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"

SF Code Analyzer Integration

# 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

Remediation Patterns

FindingVulnerable CodeFixed Code
SOQL InjectionDatabase.query('...WHERE Name=\'' + name + '\'')[SELECT Id FROM Account WHERE Name = :name]
Missing Sharingpublic class MyService {public with sharing class MyService {
FLS Bypassinsert records;Database.insert(records, AccessLevel.USER_MODE);
Hardcoded ID'012000000000ABC'Schema.SObjectType.Account.getRecordTypeInfosByDeveloperName().get('Customer').getRecordTypeId()
XSS (VF){!userInput}{!HTMLENCODE(userInput)}

Related

  • Constraint: sf-security-constraints (co-activates for enforcement rules)
  • Action: sf-security (CRUD/FLS implementation procedures)