Skip to main content

The AppExchange Security Review process

This page is for an ISV preparing a managed package for AppExchange distribution. It documents what the Security Review is, what it costs in time and money, what tooling Salesforce runs, and where Vulkro fits alongside the tools Salesforce mandates.

The page is reference material. The companion document AppExchange readiness report covers the artifact vulkro-sf appexchange-report produces.

What the review is

Every ISV-distributed managed package on AppExchange passes the AppExchange Security Review before it can be listed. The review is run by Salesforce's Product Security team. A submission goes through both an automated pass and a manual reviewer pass against the published checklist.

The review applies to:

  • First-time submissions of a new managed package.
  • Significant changes to an existing listed package (the review can be triggered when new components, new permission sets, or new external callouts are added).
  • Re-submissions after a failed review.

A package without a passing review cannot be listed; the listing is removed if a review lapses.

What it costs

Money

Each submission attempt costs $999. A failed attempt does not refund: you pay $999 again to re-submit. The review fee is set by Salesforce and is the standard Partner Program rate.

Time

The published round-trip is approximately two to three weeks per revision. In practice the timeline depends on the queue depth and how completely the submitter has prepared the supporting materials. A submission that bounces for missing documentation can take longer than one that bounces on a code finding, because the documentation re-review goes back to the queue.

Pass rate

Industry rough estimate places the first-time failure rate near 50%. The single largest cause is CRUD/FLS enforcement gaps: the Apex code performs DML or queries without checking object-level or field-level access first. Salesforce's own Top 20 vulnerabilities post ranks CRUD/FLS as the number one reason for failure.

The combined cost of a first-time failure is therefore approximately $1998 in fees plus four to six weeks of calendar time, before counting the engineering time to find and fix the failing findings.

What the reviewer runs

The automated pass uses a fixed tool chain. Knowing what the reviewer runs is the first step to passing on the first attempt.

sfdx-scanner (the mandatory baseline)

Salesforce ships its own static-analysis CLI called sf-cli scanner (formerly sfdx-scanner). It wraps:

  • PMD Apex: a published rule set covering security, error-prone patterns, performance (governor limits), best practices, and code style.
  • ESLint: the standard JavaScript linter, configured for the Lightning Web Components surface.
  • RetireJS: a vulnerable-JavaScript-library scanner that flags any packaged StaticResource carrying a known CVE.
  • Salesforce Graph Engine: a flow-sensitive engine that runs on top of PMD and emits a smaller set of higher-precision findings (CRUD/FLS path analysis, taint tracking).

The reviewer runs sf-cli scanner over the submitted package as the first automated step. A submission that fails sfdx-scanner is rejected before the manual review begins.

This means passing sfdx-scanner is necessary but not sufficient. Every ISV runs it as part of their submission prep.

Checkmarx CxSAST

Salesforce also runs Checkmarx CxSAST, an enterprise SAST tool, on the submitted source. Checkmarx contributes additional taint analysis and the historical baseline against which industry-pattern findings are caught.

Manual review

A human reviewer walks the AppExchange Security Requirements Checklist section by section. The reviewer reads the documentation the ISV submitted, inspects the code where the automated tools flagged something to be examined, and verifies the package behaves the way the documentation claims.

The eight checklist categories are:

#CategoryWhat the reviewer checks
1Authentication & session managementCookies use the SECURE flag; session invalidated on logout; SessionID never sent to external systems; OAuth or Integration Users for outbound calls.
2Authorization (CRUD / FLS / sharing)Explicit CRUD and FLS check before every DML / query; WITH USER_MODE or WITH SECURITY_ENFORCED on SOQL; every Apex class declares a sharing mode (with sharing, without sharing, or inherited sharing).
3Input validationNo SOQL injection (bind variables or String.escapeSingleQuotes); XSS-safe rendering; no CSRF on state-changing endpoints.
4Output encodingAll user-rendered content encoded for its sink (HTML / JS / URL); CSP-safe Lightning rendering.
5CryptographyNo MD5 / SHA-1 for authentication; no static IV; no Math.random() for tokens; AES-256 minimum; key handling through Crypto.encryptWithManagedIV.
6Communication securityAll callouts over HTTPS; TLS 1.2 minimum; valid CA chain; CSP Trusted Sites for remote resources; Named Credentials for outbound auth.
7Logging and error handlingNo PII in debug logs; no stack traces to users; no application secrets in System.debug; error pages do not leak system data.
8Secrets storageNamed Credentials, Protected Custom Settings, or Protected Custom Metadata; never hardcoded in source.

Additional review areas

Beyond the eight code-level categories, the review covers:

  • External Sharing: every endpoint, every Named Credential, every Connected App callback URL the package introduces.
  • Access Control: the permission set or permission set group the installation creates; every permission it grants must be justified.
  • OAuth and Connected Apps: every Connected App in the package goes through scope-by-scope justification.
  • Sensitive Data Handling: which standard or custom objects the package reads or writes, with field-level rationale for sensitive fields.
  • Component Security: LWC, Aura, and Visualforce surface exposure; iframe usage; postMessage handlers.
  • Vulnerability Disclosure: the ISV's published process for receiving and responding to vulnerability reports.

The Salesforce Security Requirements Checklist on the Partner Community is the authoritative version of this list.

How Vulkro maps to the checklist

Vulkro's detector taxonomy is mapped to the checklist sections in the AppExchange readiness report. The vulkro-sf appexchange-report command generates a single self-contained HTML file grouped by checklist section, with PASS / FAIL / NOT EVALUATED per section and a per-finding table on every FAIL.

The mapping is published: every Vulkro rule ID that contributes to a checklist section is named in the report's section header, so an auditor or reviewer can trace any finding back to the checklist row it gates.

Why Vulkro does not replace sfdx-scanner

sf-cli scanner is Salesforce-mandatory. The reviewer runs it on every submission. The ISV's job is to pass that pass first; nothing Vulkro produces removes that requirement.

Vulkro is complementary, not a replacement:

  • Vulkro covers categories sfdx-scanner does not. Metadata-side posture (SecuritySettings, sharing rules, Profile and Permission Set over-privilege, Connected App scopes, Named Credential configuration), Agentforce / GenAI surface (the ForcedLeak class-bypass detector), and the 2025-26 breach-class map (Drift / Gainsight / AuraInspector / ShinyHunters) are all outside sfdx-scanner's scope.
  • Vulkro tightens what sfdx-scanner already catches. Several PMD Apex rules are imprecise enough that ISVs routinely tune them off. The Vulkro detectors for the same patterns ship at higher confidence with explicit fix guidance per finding.
  • Vulkro emits the readiness HTML. Reviewers do not consume PMD's text output as a readiness artifact. The AppExchange readiness report is the artifact the ISV attaches to their submission package as a pre-submission self-check.

The recommended pre-submission flow is therefore: run sfdx-scanner first and fix everything it flags; then run vulkro-sf scan and vulkro-sf appexchange-report to close the residual gaps and generate the readiness artifact.

Where to go next