Do not pay $999 to fail.
The Salesforce AppExchange Security Review costs $999 per submission attempt. Roughly half of first-time submissions fail and round-trip through 2 to 3 weeks of vendor feedback per revision. sfdx-scanner is mandatory but it only runs PMD, ESLint, RetireJS, and a Salesforce Graph engine. It does not perform CRUD/FLS taint analysis, it does not flag named-credential misconfiguration, and it does not produce a checklist-aligned report you can read like an auditor.
Vulkro does. Offline, on your laptop, before you click submit.
What the AppExchange Security Review actually checks
The published checklist has 10 sections. The big ones:
- Object and field permissions (CRUD/FLS): every DML and SOQL
call must have an
isAccessible / isCreateable / isUpdateable / isDeletablecheck (orWITH SECURITY_ENFORCED, orSchema.stripInaccessible, oras user, orfflib_SecurityUtils, orCanTheUser). Missing or partial enforcement is the single most common failure reason. - Sharing model:
without sharingon classes that handle record data without an explicit ownership check is a hard fail. - External integrations: hardcoded passwords in named credentials, missing IP restrictions, OAuth scopes broader than the integration actually needs.
- Sensitive data storage: secrets in custom settings, custom
metadata types, or
Protected Custom Settingsthat turn out not to be protected when you look at the profile that owns them. - Lightning Component (LWC + Aura):
lwc:dom="manual"plusinnerHTML, unsanitized@wirereturns, secrets written tolocalStorageorsessionStorage. - Visualforce:
escape="false"paired with a reflected merge field;<apex:includeScript>with a dynamic URL. - Flow:
runInMode = SystemModeWithoutSharing, hardcoded org IDs in<stringValue>elements, DML inside system-context Flows. - Profiles + permission sets:
View All Data,Modify All Data,Customize Application,Author Apexgranted to non-admin profiles. - Connected apps:
FullOAuth scope when a narrower scope would do. - Code quality: PMD-level issues plus deeper interprocedural findings.
Vulkro's Salesforce detectors cover all 10. The
vulkro sf-appexchange-report subcommand renders an HTML report
grouped by these exact 10 sections, pinned to the checklist version
on the day you ran it, so you can hand it to your reviewer (or your
own team) and walk the list before paying $999.
What sfdx-scanner misses
sfdx-scanner is the floor. Vulkro is the prep layer above it.
| Issue class | sfdx-scanner | Vulkro |
|---|---|---|
| Hardcoded secrets in Apex literals | partial (regex on a few patterns) | yes, with provider-key family detection |
| SOQL injection (single-line concat) | yes | yes |
| SOQL injection (multi-line concat across method boundaries) | no | yes (cross-class taint) |
without sharing audit | no | yes (severity tracks sharing mode) |
| Insecure deserialization | no | yes |
| Callout credentials in code | no | yes |
| CRUD/FLS posture per method (request-reachable, DML reach, enforcement reach) | no | yes (intra-class + cross-class call graph) |
| IDOR / BOLA (caller-controlled record Id, no ownership check) | no | yes |
Mass-assignment (JSON.deserialize of caller input into SObject) | no | yes |
| Open redirect (PageReference from request param) | no | yes |
Visualforce escape="false" reflected merge field | partial | yes, with $Resource / $Label / JSENCODE wrapping suppression |
LWC lwc:dom="manual" + innerHTML | no | yes |
Flow runInMode system context | no | yes |
| Named credential hardcoded passwords | no | yes |
Connected app Full scope | no | yes |
| Profile over-privilege (View All / Modify All) | no | yes |
| Checklist-aligned HTML report | no | yes (10 sections, pinned to the published checklist) |
Detector packs for the full Salesforce surface
Vulkro covers the full Salesforce surface, not just core Apex. Each
pack self-activates when its markers are present in your
sfdx-project.json repo, so a managed package that only touches
Apex + LWC never pays the walk cost on the B2C Commerce or Heroku
Connect paths.
| Pack | What it covers | Doc |
|---|---|---|
| PMD-for-Apex | Industry-standard Apex linter with a Vulkro-curated security-only ruleset. Replacement for the sfdx-scanner Apex pack. | scan-with-pmd |
| ESLint LWC ruleset | Lightning Web Components linting with the LWC-specific rules enabled. | scan-with-eslint |
| RetireJS | CVE-bearing JS in staticresources/, vendored LWC, and Aura. | scan-with-retirejs |
| B2C Commerce Cloud | Cartridge + SFRA storefront security rules. | sf-b2c-commerce |
| Marketing Cloud | AMPscript injection, SSJS, SQL Query Activity, Cloud Pages, REST customisations. | sf-marketing-cloud |
| Industries Clouds | Health Cloud and Financial Services Cloud, including PHI cross-component leakage. | sf-industries-clouds |
| CRM Analytics | SAQL injection, dashboard binding to tainted free-text input, row-level security on PII datasets, hardcoded SF IDs. | sf-crm-analytics |
| Salesforce Functions | Node + Java runtime context credential leakage, payload validation gap, outbound rate limiting, infinite-loop budget burn. | sf-functions |
| Heroku Connect | Mapping config, Postgres bridge without pgcrypto, write-back conflict policy, plaintext PG URL, hardcoded REST API token. | sf-heroku-connect |
How the cycle works
- Build your managed package in your
sfdx-project.jsonrepo. - Run
vulkro sf-appexchange-report force-app -o readiness.html. - Open the HTML report. Walk the 10 sections. Fix what's flagged.
- Re-run. When the report says READY, submit to Salesforce.
- If Salesforce flags something new, re-run Vulkro with the reviewer's notes in hand to find similar patterns elsewhere in the codebase.
The whole loop runs on your laptop. Nothing about your unreleased managed package leaves your machine.
Get it for your submission
Vulkro for Salesforce is sold by conversation. Email [email protected] with your app name, planned submission date, and which Salesforce DX path your repo lives at. We reply within one business day.
Why offline matters here
Your unreleased managed package is, by definition, code that nobody outside your team has seen yet. Sending it to a SaaS scanner means it leaves your machine, gets indexed in a vendor database, and a copy lives at rest somewhere you do not control. For an ISV preparing a competitive product, that is exactly the wrong shape of data leak.
Vulkro runs entirely on your laptop. No telemetry, no upload, no
cloud LLM, no account. The detection engine and the CVE bundle
both live in the binary. Air-gap with VULKRO_OFFLINE=1 to
enforce zero network at the process boundary.
The credibility play
We do not ask you to trust the marketing. The benchmark harness is reproducible: clone the corpus, run the same commands, get the same numbers. The per-rule documentation explains every detector with positive and negative code examples. The Salesforce coverage docs list every rule that maps into each checklist section. The Salesforce methodology is the master reference: Well-Architected pillars, AppExchange Top-20, the 2025-26 breach class map, and Vulkro's detector-by-detector coverage matrix - every row labeled Covered or explicitly Out-of-Scope.
Ready to start?
Email [email protected]
Reply with your app name, planned submission date, and one sentence about the app. We reply within one business day.