41 new Well-Architected anti-pattern detectors (AP-015 through
AP-058, skipping the deliberately-unallocated AP-056). Catalog
grows from 14 to 55. New surfaces: PII / Agentforce safety
(AP-015..022), failure mitigation + dependency hygiene
(AP-023..029), data modeling (AP-030..033), application-complexity
live-org signals (AP-034..037), Validation Rule rebuilds + REST /
callout hygiene (AP-038..045), Flow execution context, Custom
Metadata / Custom Setting secrets, GDPR right-to-erasure gap
(AP-046..049), LWC / Aura JavaScript security (AP-050..052),
Visualforce page / component security (AP-053..055), live-org
Permission Set Group over-privilege (AP-057), live-org Apex
test-coverage gate (AP-058). Per-detector descriptions are on the
Anti-patterns CLI doc page; SOC 2 / HIPAA / PCI / GDPR mappings
on the Compliance pages.
New file walkers. The scanner now walks Salesforce metadata
XML (object / flow / GenAiFunction / agent / prompt template /
installed-package / external-service registration), LWC and Aura
JavaScript controllers (.js files under lwc/ and aura/),
and Visualforce pages and components (.page and .component).
The Apex .cls / .trigger walker is unchanged.
Multi-namespace project support. The scanner now reads every
namespace declared in sfdx-project.json (top-level namespace,
packageAliases keys, packageDirectories[].package) and treats
them all as the project's own namespace. New
--exclude-namespace=npe01,npe03,... CLI flag for legacy
managed-package projects (NPSP-style historical prefixes).
Suppress comments. // vulkro: ignore AP-029 (or
AP-029, AP-013, or *) on a finding's line or the line above
drops it from the output. Works in both Apex and metadata-XML
files.
.vulkro-sf.yml project config. Optional file at the scan
root with disable: [...] and extra_excluded_namespaces: [...].
SARIF v2.1.0 output (--format=sarif). Standard format for
the GitHub Security tab, SonarQube, Codacy.
JUnit XML output (--format=junit). One <testcase> per
finding so CI runners (GitHub Actions, GitLab CI, Jenkins)
surface findings as failed tests.
HIPAA + PCI compliance profiles. --compliance=hipaa adds
the 18 HIPAA Safe Harbor identifier classes; --compliance=pci
adds PCI-DSS card-data identifiers (PAN, CVV, expiry, cardholder
name, magnetic-stripe). Both flags stack
(--compliance=hipaa,pci).
Incremental scan cache. Per-file findings cached by SHA-256
- detector version + flags at
~/.vulkro/sf-antipattern-cache.json. Subsequent scans only
re-run detectors on changed files. --no-cache and
--cache-dir flags for CI / forced re-scan.
Parallel scanning (rayon). Per-file work runs across CPU
cores. Roughly half wall-time on an 8-core machine for
managed-package-scale codebases (~50k files).
Tree-sitter AST migration begins. 8 detectors now run against
the parsed Apex AST when the file parses, falling back to the
line-scanner when it doesn't: AP-001 (SOQL in loop), AP-002 (DML
in loop), AP-004 (Empty catch), AP-008 (Schema describe in loop),
AP-013 (SOQL without WHERE/LIMIT), AP-014 (@isTest SeeAllData),
AP-018 (Agentforce action without validation), AP-023 (Catch-and-
rethrow), AP-024 (Partial-success DML). Multi-line SOQL / DML
now caught for AP-001 / AP-013 / AP-024 (was a documented
limitation). The other 20 per-file Apex detectors still run on
the line-scanner.
Cross-method taint analysis (AP-018). When an
@InvocableMethod lacks validation in its own body, the detector
now asks the call graph whether any helper the method invokes
validates the input first. Real cross-method taint; AP-018
suppresses correctly when validation lives in a helper.
SOC 2 Trust Services Criteria mapping. Every detector
(AP-001..AP-058) is mapped to CC6.1 / CC6.6 / CC7.2 / CC8.1 on
the Compliance SOC 2 page.
Live org coverage UI. New Quality -> Live org coverage sub
tab in the desktop console. Reads OrgSnapshot.coverage (populated
by a new Tooling API query against ApexCodeCoverageAggregate),
renders per-class coverage with the 75% AppExchange gate.
Claude Code Skill. Install the skill at .claude/skills/vulkro-sf/ to get slash commands inside Claude Code: /vulkro-sf scan to scan your project (returns a compact summary instead of dumping 30k tokens into the chat), /vulkro-sf show <id> to see one finding, /vulkro-sf diff <baseline> to see only what changed, /vulkro-sf grep <pattern> to filter, /vulkro-sf suppress <id> to add a // vulkro:disable annotation in place, /vulkro-sf fix <id> to apply an auto-safe fix when available, /vulkro-sf explain <id> for the rule rationale, /vulkro-sf rules list, /vulkro-sf intel status. Scans cache by working-tree hash so re-runs are instant. Built so Claude Code users can run a Salesforce security review without ever leaving the chat.
New live-org audit subcommands. Beyond org status / org perms /
org packages, the CLI now reaches nine more live posture surfaces:
org login-history: flags admin logins from untrusted IPs,
failed-login bursts, and admin Application-type logins that
bypass MFA.
org audit-trail: recent privilege escalations from
SetupAuditTrail and out-of-hours Setup edits.
org health-check: pulls the Salesforce-computed Health Check
score and lists every risk category with a non-zero risk count.
org effective-perms: the cumulative permissions users actually
hold right now (per-object ModifyAllRecords / ViewAllRecords,
field-level Read/Edit on PII-shaped fields, and which active
users currently sit on a broad-system-perm permset).
org connected-apps: live Connected App OAuth: Full-scope apps
with active tokens, apps with only stale tokens, cleartext
callback URLs.
org named-credentials: live Named Credential audit: cleartext
HTTP endpoints, Anonymous principals paired with an AuthProvider
(baked-in credential), merge-fields-in-body enabled.
org guest-live: Experience Cloud guest exposure: self-registration
on, default guest access on a Site, Chatter guests.
org domain: MyDomain SSL: domains that still allow HTTP,
mixed Standard + CustomDomain rollouts.
org mail: OrgWideEmailAddress with "all profiles can send-as",
EmailServicesAddress on non-salesforce.com domains.
All output the same exit-code contract (0 clean, 1 findings, 2 error)
and the same --format table|json|sarif flags as org perms.
SecuritySettings rules wired into org perms. The session-timeout,
password-policy, clickjacking, and CSRF-on-POST rules (SF-SESSION-001/-002,
SF-PWD-001/-002/-003, SF-CLICKJACK-001, SF-CSRF-001) ran only through
the desktop console before; they now run on the CLI too.
Per-object record-permission detector. A profile or permission set
that grants <modifyAllRecords>true</> or <viewAllRecords>true</> on a
specific object is the per-object equivalent of ModifyAllData /
ViewAllData and was not inspected before. Three sub-rules:
modify-all-records (High), view-all-records (Medium), view-all-records on
a PII-shaped object (escalates to High). Skips Salesforce-delivered
standard profiles and the standard System Administrator file.
PII custom-field cleartext detector. Flags objects/<Obj>/fields/<Field>.field-meta.xml
files whose developer name matches a PII shape (SSN, DOB, bank account,
government ID, medical record) but whose <type> is plain Text /
TextArea / Number / Phone / Email / Url and which carry no <encrypted>
flag and are not formula-derived.
Custom-object sharing-model correlator. Reads <sharingModel> on a
custom object and flags non-Private values (Read, ReadWrite,
ReadWriteTransfer, FullAccess, ControlledByParent / Campaign /
LeadOrContact) when the object also carries PII-shaped fields. Skips
__mdt, __b, __e, and standard objects.
Brute-force-able guest entry detector. Flags @AuraEnabled methods
on without sharing Apex classes that query a PII column and gate the
response on a low-entropy equality check (last-4 SSN, right-N, endsWith)
with no rate limit or lockout. The 10,000-attempt search space is
iterable by a guest caller until a match is found.
@AuraEnabled mutator authorization detector. Flags @AuraEnabled
Apex methods that DML an SObject without a visible authorization gate
(FeatureManagement.checkPermission, a PermissionSetAssignment
lookup, a profile-name comparison, WITH SECURITY_ENFORCED, as user
mode, or a custom require*Permission / assertRole helper).
LLM / Agentforce detector subpack (5 sub-rules). Closes the Apex
callout surface for LLM integrations:
- User input flowing into an LLM prompt body without escaping
(CWE-1427).
- Untyped LLM response deserialization (LLM output is
non-deterministic; reflecting it downstream is a content-injection
vector).
- LLM callout missing
max_tokens and / or setTimeout (runaway
prompt blows the CPU governor and racks up vendor cost).
- Single LLM Named Credential referenced from three or more classes
(rotation hazard).
- LLM model / endpoint configuration stored in an unprotected
__mdt record (anyone with Customize Application can redirect
every LLM call without a deployment).
Platform Event publish-authorization detector. Flags
EventBus.publish calls reachable without an authorization gate from
an @AuraEnabled or REST entry (High), from a broadly-callable
non-entry method (Medium), or inside a trigger body (Low,
informational).
Async-class sharing-context detector. Queueable / Batchable /
Schedulable / @future classes with no with sharing modifier (Apex
default in async dispatch is system mode) get flagged when the body
references a PII-shaped sObject; severity escalates one notch when the
entry method DMLs PII without a prior WITH SECURITY_ENFORCED.
Custom Metadata reference-tamper detector. Flags *.md-meta.xml
records that are <protected>false</protected> AND store a string
value referencing a sensitive Salesforce resource (Named Credential,
Connected App, RemoteSite, AuthProvider, External Credential, endpoint
URL, OAuth callback). Anyone with Customize Application can rewrite
the reference and redirect every Apex callout without a deployment.
Custom Setting credential detector. Walks
objects/<Obj>__c/<Obj>__c.object-meta.xml for <customSettingsType>
and flags credential-shaped field names (API_Key, Secret, Token,
Password, Private_Key, Connection_String, etc.) on the sibling
fields. Severity scales by setting shape: Hierarchy + Public is
Critical, Hierarchy + Protected is High, List is Medium.
Static-resource SCA. Flags vulnerable copies of jQuery (< 3.5.0
prototype pollution / XSS), Lodash (< 4.17.21), CryptoJS (< 4.2.0
weak PBKDF2 default), Moment.js (deprecated), AngularJS 1.x (EOL
2022), and Bootstrap (< 4.3.1 XSS) shipped via staticresources/.
lwc:dom="manual" detector. Flags LWC templates that use the
manual directive: the host element bypasses Lightning Web Security
sandboxing, so any innerHTML set on it from the component's JS
renders arbitrary HTML (including <script>) in the user's tab DOM.
// vulkro:disable source-annotation suppression. Inline
annotations now let you mark a verified-OK line so future scans skip
the finding: // vulkro:disable next-line <rule-id>,
// vulkro:disable-line <rule-id>, // vulkro:disable-file <rule-id>,
and the <!-- ... --> form for XML / HTML / *-meta.xml files. The
CLI reports how many findings were suppressed; --no-suppress (or
VULKRO_NO_SUPPRESS=1) short-circuits the filter for CI lanes that
need the full picture.
AP-004 (Empty catch) escalation. Empty catch blocks now escalate
to High severity when the surrounding try body performs DML, an HTTP
callout, an EventBus.publish, a queued async job, or a
Messaging.sendEmail. Silent mutation failure is data corruption, not
a Medium concern.