Why This Exists
I’ve been doing Salesforce pentests for close to a year now. Salesforce Experience Cloud sites (formerly Communities) sit on top of the Aura/Lightning framework, and the privilege escalation surface is enormous. Misconfigured object permissions, overly permissive guest user profiles, exposed Apex controllers. These are not edge cases. They show up in almost every engagement.
The manual process looks like this: fire up Burp, intercept Aura requests, swap out object names and action descriptors, check responses for data leakage, repeat for dozens of objects. It works, but it is slow, repetitive, and easy to miss things. I wanted something that would handle the enumeration automatically so I could focus on the parts that actually require thinking, like chaining findings into real attack paths and proving write access.
The other motivation is community contribution. Salesforce Aura security testing is not well documented outside of a handful of blog posts and conference talks. The protocol is undocumented, the attack surface is poorly understood, and most organisations running Experience Cloud sites have no idea what their guest user can access. Publishing a tool and the research behind it seemed like the right thing to do.
What aura-privesc Does
The scanner automates the discovery and enumeration phase of Aura privilege escalation testing. It runs in four phases.
Phase 1: Discovery
The tool probes common Aura endpoint paths (/s/sfsites/aura, /sfsites/aura, /aura, /s/aura), fetches the community HTML, and extracts three critical values: the fwuid (framework UID that changes with every Salesforce release), the aura.context JSON blob, and the application name. These are required for every subsequent Aura request. Getting them wrong, or encoding them incorrectly, means silent failures.
Phase 2: User Context
Once the endpoint is established, the scanner identifies the current user via getProfileMenuResponse and checks whether SOQL queries are possible. This tells you whether you are hitting the site as a guest user or an authenticated session, and what the baseline access level looks like.
Phase 3: Object Enumeration
This is the core of the tool. For each object in the scan list (44 standard Salesforce objects by default, plus any custom objects you supply), it does two things:
getObjectInfo- Retrieves CRUD permission flags. Can the current user create, read, update, or delete records on this object?getItems- Attempts to actually retrieve records. Permission flags can lie. An object might reportreadable: truein its metadata but return zero records, or the request might fail entirely. The only way to confirm is to try.
After enumeration, a validation pass re-checks every finding to filter false positives. Salesforce sometimes returns success responses for objects that are not genuinely accessible. The validator re-issues the request and checks for real metadata in the response.
For objects where write permissions are detected, the scanner can automatically test create, update, and delete operations. It generates safe test values based on field metadata (strings get a timestamped AuraPrivescTest_HHMMSS marker, emails get [email protected], picklists use the first valid value). Created records are cleaned up by deleting them after the test. It never touches existing data.
Phase 4: Apex Controller Testing
The scanner discovers @AuraEnabled Apex controllers by parsing JavaScript files loaded by the community page, then tests each method by calling it through the ApexActionController/execute wrapper. Methods are classified as CALLABLE (got past the access check), DENIED (access check failed), or NOT_FOUND. Even methods that error out after the access check are classified as callable, because the access check is the security boundary. What happens after is a logic bug, not a permission issue.
The Report
The primary output is a self-contained HTML report. Dark theme, no external dependencies, works offline. It includes:
- A summary dashboard with counts of accessible objects, writable objects, proven write operations, and callable Apex methods
- A sortable, filterable objects table where each row expands to show sample record data
- Action buttons on every object row that copy ready-to-use curl commands to your clipboard for
getObjectInfo,getItems, Create, Update, and Delete operations - An Apex methods table with the same treatment
The curl commands are the starting point for manual CRUD validation. The scan tells you what is exposed. The report gives you the commands to prove it, modify field values, swap in record IDs, and run them through your proxy.
The Aura Protocol
The Aura protocol is not publicly documented by Salesforce, and getting the implementation right was the bulk of the engineering effort. A few things that tripped me up:
The action ID matters. Every Aura action needs an ID field. The current value is "123;a". Using "0" or "1" causes failures on some endpoints. This is not documented anywhere.
clientOutOfSync recovery is essential. Salesforce rotates fwuid values regularly. When a request hits the server with a stale fwuid, the response contains the new value in one of two formats: an exceptionEvent with clientOutOfSync type, or a coos field in the response context. The client needs to handle both, extract the new fwuid, and retry automatically. Without this, the scanner would break every time Salesforce pushes an update.
getItems parameters are specific. The working combination is layoutType:"FULL", pageSize:100, currentPage:0, useTimeout:false, getCount:false, enableRowActions:false. Deviate from this and you get empty results or errors. I found these by intercepting real Aura traffic in Burp and comparing working requests against failing ones.
Recon Mode
For engagements where you have a privileged org user (internal pentest, white-box assessment), the recon subcommand uses the Salesforce CLI to enumerate every sObject and every @AuraEnabled Apex method visible to that user. It outputs two text files that you feed into the main scan against the community endpoint.
This is the privilege escalation gap analysis. The recon tells you what the admin can see. The scan tells you what the guest user (or low-privilege authenticated user) can see. The delta between those two lists is your finding.
# Step 1: Recon with a privileged user
aura-privesc recon -u https://instance.sandbox.my.salesforce.com --alias myalias
# Step 2: Scan the community endpoint with the recon output
aura-privesc -u https://target.my.site.com \
--endpoint '/s/sfsites/aura' \
--authenticated \
--objects-file recon_objects.txt \
--apex-file recon_apex.txt \
--proxy http://127.0.0.1:8080 --insecure
How It Was Built
The entire tool was built in a single day with Claude Code. The architecture is straightforward:
client.py- Async HTTP client implementing the Aura protocol envelope, withclientOutOfSyncrecovery and semaphore-bounded concurrencydiscovery.py- Endpoint probing and context extraction from community HTMLenumerator.py- Object permission checking and record retrievalcrud.py- Automated write operation testing with safe test values and cleanupapex.py- Apex controller discovery from JS files and method testingvalidator.py- False positive filtering via re-verificationproof.py- Curl command generation for every findingoutput/html_output.py- Self-contained HTML report with embedded CSS and JavaScript
The development loop was tight. Build a phase, fix the protocol issues that surfaced, move on. Most of the iteration was on the Aura protocol encoding. The scanner logic itself is straightforward once you can reliably talk to the endpoint.
What I’ve Found With It
Guest user profiles on Experience Cloud sites frequently have read access to objects like Account, Contact, Case, User, and Organization. Sometimes write access. Sometimes access to custom objects containing sensitive business data.
The most common issue is overly permissive guest user profiles combined with objects that were never intended to be exposed through the community. Salesforce’s permission model is complex. Object-level CRUD permissions, field-level security, sharing rules, org-wide defaults. It is easy to get wrong, and most organisations do.
Apex controllers are the other major finding category. Custom @AuraEnabled methods built for internal Lightning components that are also reachable through the community endpoint. These often bypass the standard object permission model entirely because the Apex code runs in system context.
What’s Next
The tool handles enumeration and proof-of-concept generation. The areas I want to expand:
- SOQL injection testing for endpoints that accept query parameters
- Field-level security checks to identify specific sensitive fields exposed on accessible objects
- Broader Apex method fuzzing with parameter type inference
- Differential analysis built into the tool itself, comparing recon output against scan results automatically
- Privileged configuration review to audit guest user profiles, sharing rules, and org-wide defaults from an authenticated session
The code will be published on GitHub once I’ve cleaned up a few rough edges. If you’re doing Salesforce security work, I’d welcome contributions and feedback.
aura-privesc is intended for authorised security testing only. Only use it against systems you have explicit permission to test.