Swiss Army knife for auditing Salesforce Experience Cloud (Aura) misconfigurations.
Project description
Salesforce Security AI Scanner
Built by phanimca — an AI-powered security auditing tool for Salesforce Experience Cloud (Aura).
Live Demo: https://phani-aura-inspector.vercel.app
Salesforce Security AI Scanner is a security auditing toolkit for Salesforce Experience Cloud (Aura). It automates the discovery of misconfigured endpoints, over-privileged guest access, IDOR vulnerabilities, and Apex controller weaknesses. It ships as four integrated surfaces: a command-line scanner, a web dashboard, a Gradio desktop UI, and a FastMCP server for AI assistant integration.
For background, see the Mandiant blog post: Auditing Salesforce Aura Data Exposure.
Author
| Author | Phani |
| phani.dummy@hotmail.com | |
| Live App | https://phani-aura-inspector.vercel.app |
| PyPI | phani-aura-inspector |
| License | Apache 2.0 |
Table of Contents
- Features
- Architecture
- Requirements
- Environment Variables
- Installation
- CLI Usage
- Web Dashboard
- Gradio UI
- MCP Server
- Docker Compose
- Testing
- Licenses
Features
- Guest & authenticated scanning — discovers accessible records from both Guest and Authenticated Salesforce contexts
- Three scanner engines running in sequence:
AuraFuzzer— endpoint fuzzing for over-privileged guest controller accessIDORScanner— insecure direct object reference detection across Salesforce object prefixesApexScanner— custom controller system-mode execution pattern detection
- GraphQL probe — uses the undocumented Aura GraphQL method to count exposed records (skippable with
--no-gql) - AI-powered analysis — optional GPT-4o enrichment: risk scoring, critical pattern detection, and priority remediation actions; gracefully degrades to rule-based analysis when no API key is present
- Remediation advisor — maps each finding to OWASP API Security 2023 refs, Salesforce Setup steps, and Apex code examples
- Web dashboard — FastAPI app with SQLite persistence, JWT auth, scan history, and printable HTML reports
- MCP server — FastMCP server exposing all scanner capabilities as tools consumable by Claude Desktop, VS Code Copilot, and any MCP-compatible AI assistant
Architecture
aura-inspector/
├── src/
│ ├── aura_cli.py # CLI entry point
│ ├── aura_helper.py # Aura HTTP client, endpoint discovery
│ ├── colored_logger.py # Terminal colour / logger config
│ ├── scanners/
│ │ ├── base_scanner.py # Severity enum, ScanFinding dataclass, BaseScanner
│ │ ├── aura_fuzzer.py # Guest controller fuzzer
│ │ ├── idor_scanner.py # IDOR probe across SF object prefixes
│ │ └── apex_scanner.py # Apex system-mode pattern detector
│ ├── ai_agents/
│ │ ├── scan_agent.py # SecurityScanAgent — orchestrates all three scanners + GPT-4o
│ │ └── remediation_advisor.py # OWASP → Salesforce remediation lookup
│ ├── mcp/
│ │ └── server.py # FastMCP server (4 tools, 2 resources)
│ ├── web/
│ │ ├── main.py # FastAPI routes (port 8080)
│ │ ├── auth.py # JWT + bcrypt password hashing
│ │ ├── database.py # SQLAlchemy models (User, ScanJob, Finding, AiAnalysis)
│ │ ├── scan_runner.py # Background scan daemon thread
│ │ └── templates/ # Jinja2 templates (Bootstrap 5.3 dark theme)
│ └── ui/
│ └── app.py # Gradio desktop UI (port 7860)
├── requirements.txt # Core: requests only
├── requirements-ai.txt # openai, tenacity
├── requirements-mcp.txt # fastmcp, structlog
├── requirements-web.txt # fastapi, uvicorn, sqlalchemy, jinja2, passlib, python-jose
├── Dockerfile # Gradio UI image
├── Dockerfile.web # Web dashboard image
├── Dockerfile.mcp # MCP server image
└── docker-compose.yml # All three services
Requirements
- Python 3.12+
- Windows:
.venv\Scripts\python.exe| Linux/macOS:.venv/bin/python
| Surface | Extra requirements |
|---|---|
| CLI only | requests (base install) |
| AI analysis | requirements-ai.txt (openai>=1.0.0, tenacity>=8.2.0) |
| Gradio UI | requirements-ai.txt + gradio>=4.0.0 |
| MCP server | requirements-mcp.txt (fastmcp>=2.0.0, structlog>=24.1.0) + AI deps |
| Web dashboard | requirements-web.txt |
Environment Variables
All configuration is driven by environment variables — no config files are needed.
For local development, create a .env file at the repo root (it is git-ignored).
Security note: Never commit secrets to source control.
Required — app will not work correctly without these
| Variable | Example | Description |
|---|---|---|
DATABASE_URL |
postgresql://user:pass@host/db?sslmode=require |
Persistent storage. Without it the app uses ephemeral SQLite in /tmp and all data is lost on every serverless cold start. Use Neon (free tier) or Vercel Postgres. |
SECRET_KEY |
openssl rand -hex 32 output |
Signs JWT session cookies. The built-in default is public and insecure in production — always override this. |
APP_BASE_URL |
https://phani-aura-inspector.vercel.app |
Canonical public URL of the app. Required for Salesforce OAuth — without it the OAuth redirect URI uses the ephemeral Vercel deployment URL and causes a redirect_uri_mismatch error on every new deploy. |
Required for Salesforce authenticated scans
Create a Salesforce Connected App with OAuth enabled.
Set the Callback URL to https://<your-app>.vercel.app/auth/sf/callback.
Enable scopes: api, web.
| Variable | Example | Description |
|---|---|---|
SF_CLIENT_ID |
3MVG9... |
Connected App Consumer Key |
SF_CLIENT_SECRET |
ABC123... |
Consumer Secret (optional for public/PKCE apps) |
SF_INSTANCE_URL |
https://login.salesforce.com |
Login URL — use https://test.salesforce.com for sandbox. Defaults to production. |
Required for AI-powered analysis (GPT-4o / GitHub Models)
Without these, every scan falls back to rule-based risk scoring automatically.
| Variable | Example | Description |
|---|---|---|
OPENAI_API_KEY |
ghp_... (GitHub PAT) or sk-... (OpenAI key) |
API key for the AI analysis endpoint |
OPENAI_BASE_URL |
https://models.github.ai/inference |
Base URL for an OpenAI-compatible endpoint. Leave unset to use OpenAI directly. Set to the GitHub Models URL to use GitHub Models (free with a PAT that has models:read permission). |
OPENAI_MODEL |
openai/gpt-4o-mini |
Model name. Use openai/gpt-4o-mini for GitHub Models or gpt-4o for OpenAI. |
GitHub Models quick-start (free alternative to OpenAI)
- Generate a GitHub Personal Access Token with Models → Read permission.
- Set the three variables above in Vercel.
- No Connected App, no paid subscription needed.
Optional — have safe defaults
| Variable | Default | Override when |
|---|---|---|
DEFAULT_ADMIN_USERNAME |
phani |
You want a different admin username |
DEFAULT_ADMIN_EMAIL |
phani.dummy@hotmail.com |
You want a different admin email |
DEFAULT_ADMIN_PASSWORD |
Admin@123 |
Change this — the default is public |
WEB_PORT |
8080 |
Running the web server locally on a different port |
Set automatically by Vercel (do not add manually)
| Variable | Description |
|---|---|
VERCEL |
Set to 1 on every serverless invocation |
VERCEL_URL |
Deployment-specific URL (changes per deploy — do not use for OAuth redirect URIs) |
VERCEL_PROJECT_PRODUCTION_URL |
Stable production alias — used as fallback if APP_BASE_URL is not set |
WEB_ENV |
Set to production via vercel.json |
Vercel setup checklist
Go to your Vercel project → Settings → Environment Variables and add:
DATABASE_URL = postgresql://... (Production + Preview)
SECRET_KEY = <random 32-byte hex> (Production + Preview)
APP_BASE_URL = https://<your-alias>.vercel.app (Production only)
SF_CLIENT_ID = <Connected App key> (Production + Preview)
SF_CLIENT_SECRET = <Consumer secret> (Production + Preview)
OPENAI_API_KEY = <GitHub PAT or sk-...> (Production + Preview)
OPENAI_BASE_URL = https://models.github.ai/inference (Production + Preview)
OPENAI_MODEL = openai/gpt-4o-mini (Production + Preview)
DEFAULT_ADMIN_PASSWORD = <strong password> (Production only)
After adding variables, redeploy: vercel --prod --yes
Local .env example
# Required
DATABASE_URL=sqlite:///./data/aura_inspector.db
SECRET_KEY=replace-with-a-long-random-string
APP_BASE_URL=http://localhost:8080
# Salesforce OAuth
SF_CLIENT_ID=3MVG9...
SF_CLIENT_SECRET=ABC123...
# AI analysis via GitHub Models (free)
OPENAI_API_KEY=ghp_your_github_pat
OPENAI_BASE_URL=https://models.github.ai/inference
OPENAI_MODEL=openai/gpt-4o-mini
# Admin account
DEFAULT_ADMIN_PASSWORD=MyStrongPassword!
Installation
Clone and set up a virtual environment
# Windows
git clone https://github.com/phanimca/aura-inspector
cd aura-inspector
python -m venv .venv
.venv\Scripts\Activate.ps1
# Linux / macOS
git clone https://github.com/phanimca/aura-inspector
cd aura-inspector
python3 -m venv .venv
source .venv/bin/activate
Install dependencies
# CLI only (minimal)
pip install -r requirements.txt
# CLI + AI analysis
pip install -r requirements.txt -r requirements-ai.txt
# MCP server
pip install -r requirements.txt -r requirements-ai.txt -r requirements-mcp.txt
# Web dashboard
pip install -r requirements.txt -r requirements-web.txt
# Everything
pip install -r requirements.txt -r requirements-ai.txt -r requirements-mcp.txt -r requirements-web.txt
Install as a package (optional)
pip install -e ".[ai,mcp,web]"
This registers the console scripts: aura-inspector, aura-inspector-web, aura-inspector-mcp.
CLI Usage
Smoke test
python src/aura_cli.py -h
Guest scan (unauthenticated)
python src/aura_cli.py -U phani -u https://yoursite.my.salesforce.com
Guest scan — save output, skip GraphQL, ignore TLS errors
python src/aura_cli.py -U phani -u https://yoursite.my.salesforce.com -k --no-gql -o ./results
Authenticated scan with session cookie
python src/aura_cli.py -U phani -u https://yoursite.my.salesforce.com \
-c "sid=XXXXXXX; other_cookie=..."
Authenticated scan from a captured Aura request file
python src/aura_cli.py -U phani -r /path/to/aura_request.txt
Explicit app and aura paths (for custom site prefixes)
# Site hosted at /s with Aura endpoint at /s/sfsites/aura
python src/aura_cli.py -U phani -u https://yoursite.my.salesforce.com \
--app /s --aura /s/sfsites/aura -k -o ./results
Proxy through Burp Suite
python src/aura_cli.py -U phani -u https://yoursite.my.salesforce.com \
-p http://127.0.0.1:8080 -k
Full option reference
| Flag | Description |
|---|---|
-U / --username |
Required. Username to attribute the scan to. Looked up in the web DB; a new CLI-only account is created automatically if not found |
-u / --url |
Root URL of the Salesforce Experience Cloud site |
-c / --cookies |
Session cookies for authenticated scans |
-r / --aura-request-file |
Path to a captured request file (auto-parses cookies/token) |
-o / --output-dir |
Directory to save JSON results |
-l / --object-list |
Comma-separated list to limit object probing |
-p / --proxy |
HTTP proxy (e.g. http://127.0.0.1:8080) |
-k / --insecure |
Ignore TLS certificate errors |
--app |
Explicit app path override (e.g. /s, /myApp) |
--aura |
Explicit Aura endpoint path override (e.g. /s/sfsites/aura) |
--context |
Custom aura.context value for POST requests |
--token |
Custom aura.token value for POST requests |
--no-gql |
Skip GraphQL record-count probes |
--no-banner |
Suppress the ASCII banner |
-d / --debug |
Print debug-level output |
-v / --verbose |
Print verbose output |
Web Dashboard
The web dashboard provides a persistent scan history with authentication, a live scan status page, a severity chart dashboard, and printable HTML reports.
Live hosted version: https://phani-aura-inspector.vercel.app Default login:
phani.dummy@hotmail.com/ configured viaDEFAULT_ADMIN_PASSWORDenv var.
Start
pip install -r requirements-web.txt
python src/web/main.py
# Open http://localhost:8080
First-time setup
- Open
http://localhost:8080/registerand create an account. - Log in at
http://localhost:8080/login. - Go to New Scan → enter a target URL, choose guest or authenticated mode → Start Scan.
- The dashboard polls the scan status every 2 seconds and shows findings as they arrive.
- From a completed scan, click View Report for a printable summary.
Environment variables
See the Environment Variables section for the full reference. Key variables for the web dashboard:
| Variable | Default | Description |
|---|---|---|
SECRET_KEY |
(insecure default) | JWT signing key — must be set in production |
DATABASE_URL |
SQLite in /tmp |
PostgreSQL URL for persistent storage |
APP_BASE_URL |
auto-detected | Canonical public URL — required for Salesforce OAuth |
OPENAI_API_KEY |
(none) | Enables AI analysis; falls back to rule-based scoring |
OPENAI_BASE_URL |
(OpenAI direct) | Set to https://models.github.ai/inference for GitHub Models |
OPENAI_MODEL |
openai/gpt-4o-mini |
Model name for the AI analysis endpoint |
Routes summary
| Method | Path | Description |
|---|---|---|
| GET/POST | /login |
Login form |
| GET/POST | /register |
Registration form |
| GET | /logout |
Clears session cookie |
| GET | /dashboard |
Scan history + charts |
| GET | /scans/new |
New scan form |
| POST | /scans |
Submit and start a scan |
| GET | /scans/{id} |
Scan detail + live status |
| GET | /scans/{id}/status |
JSON polling endpoint |
| GET | /reports/{id} |
Printable HTML report |
| GET | /api/stats |
JSON stats for dashboard charts |
Gradio UI
The Gradio UI is a desktop-style browser interface on port 7860.
pip install -r requirements.txt gradio
python src/ui/app.py
# Open http://localhost:7860
MCP Server
The FastMCP server exposes all scanner capabilities as tools that any MCP-compatible AI assistant (Claude Desktop, VS Code Copilot, etc.) can call directly.
Tools
| Tool | Description |
|---|---|
run_guest_scan |
Full unauthenticated Aura scan (AuraFuzzer + IDORScanner + ApexScanner + AI analysis) |
run_auth_scan |
Same as above but authenticated via a Salesforce session cookie |
get_remediation |
Return Salesforce Setup steps and Apex code examples for an OWASP API Security ref (API1–API10) |
explain_finding |
Ask GPT-4o to explain a single finding in plain language (degrades to rule-based without an API key) |
Resources
| URI | Description |
|---|---|
scan://schema |
JSON Schema describing the full scan result object |
scan://owasp |
Supported OWASP API Security 2023 references and their titles |
Transport modes
| Mode | Use case | How to start |
|---|---|---|
stdio |
Claude Desktop, VS Code Copilot (default) | python src/mcp/server.py |
sse |
Network-accessible / Docker deployments | MCP_TRANSPORT=sse MCP_PORT=8765 python src/mcp/server.py |
Start the server
# Install MCP dependencies
pip install -r requirements-mcp.txt
# stdio (default — for VS Code / Claude Desktop)
python src/mcp/server.py
# SSE network mode
$env:MCP_TRANSPORT="sse"; $env:MCP_PORT="8765"
python src/mcp/server.py
VS Code Copilot integration
The repo ships a pre-configured .vscode/mcp.json. After installing MCP dependencies:
- Restart VS Code (the MCP config is loaded on startup).
- Open the Command Palette → MCP: List Servers → confirm
aura-inspectoris listed. - In a Copilot chat, type
#aura-inspectorto attach the server context.
Example prompts:
Run a guest scan on https://yoursite.my.salesforce.com
Get the Salesforce remediation steps for API1
Explain this finding: "Guest user can access Account records via LightningRecordList"
Claude Desktop integration
Add to your claude_desktop_config.json:
{
"mcpServers": {
"aura-inspector": {
"command": "C:/path/to/aura-inspector/.venv/Scripts/python.exe",
"args": ["C:/path/to/aura-inspector/src/mcp/server.py"],
"env": {
"OPENAI_API_KEY": "sk-..."
}
}
}
}
Testing MCP tools without an AI client
Since the tools are plain Python functions, you can call them directly:
python -c "
import sys; sys.path.insert(0, 'src')
from mcp.server import get_remediation, owasp_references
print(get_remediation('API1'))
print(owasp_references())
"
Docker Compose
The docker-compose.yml starts all three services:
| Service | Image | Port | Description |
|---|---|---|---|
aura-inspector-gradio |
Dockerfile |
7860 |
Gradio desktop UI |
aura-inspector-web |
Dockerfile.web |
8080 |
FastAPI web dashboard |
aura-inspector-mcp |
Dockerfile.mcp |
8765 |
MCP server (SSE mode) |
Start all services
# Create a .env file with your secrets first (see API Keys section)
docker compose up --build
Start a single service
docker compose up --build aura-inspector-web
Environment variables for Docker
Create a .env file at the repo root (Docker Compose picks it up automatically):
# Required
DATABASE_URL=postgresql://user:pass@host/db?sslmode=require
SECRET_KEY=replace-with-a-long-random-string
APP_BASE_URL=https://your-domain.com
# Salesforce OAuth
SF_CLIENT_ID=your-connected-app-client-id
SF_CLIENT_SECRET=your-consumer-secret
SF_INSTANCE_URL=https://yourinstance.my.salesforce.com
# AI analysis via GitHub Models
OPENAI_API_KEY=ghp_your_github_pat
OPENAI_BASE_URL=https://models.github.ai/inference
OPENAI_MODEL=openai/gpt-4o-mini
Testing
CLI smoke test
python src/aura_cli.py -h
Compile health check
python -m py_compile \
src/scanners/aura_fuzzer.py \
src/scanners/idor_scanner.py \
src/scanners/apex_scanner.py \
src/ai_agents/scan_agent.py \
src/mcp/server.py
Run pytest unit tests
pip install pytest pytest-mock
python -m pytest tests/ -v
Integration scan against a live target
# Non-interactive guest scan, results saved to ./results
python src/aura_cli.py -U phani -u https://yoursite.my.salesforce.com -k --no-gql -o ./results
Web app health check
# Start the web app, then:
curl http://localhost:8080/api/stats
MCP server health check (SSE mode)
# Start with MCP_TRANSPORT=sse, then:
curl http://localhost:8765/tools
Licenses
| Component | License |
|---|---|
| salesforce-security-ai-scanner core | Apache License 2.0 |
requests |
Apache License 2.0 |
openai Python SDK |
Apache License 2.0 |
tenacity |
Apache License 2.0 |
fastmcp |
Apache License 2.0 |
structlog |
Apache License 2.0 / MIT |
fastapi |
MIT |
uvicorn |
BSD-3-Clause |
sqlalchemy |
MIT |
jinja2 |
BSD-3-Clause |
passlib |
BSD |
python-jose |
MIT |
gradio |
Apache License 2.0 |
| Bootstrap 5.3 (web templates) | MIT |
| Chart.js (web templates) | MIT |
Developed By
- Amine Ismail
- Anirudha Kanodia
- Phani
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file phani_aura_inspector-0.3.3.tar.gz.
File metadata
- Download URL: phani_aura_inspector-0.3.3.tar.gz
- Upload date:
- Size: 104.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06e0ff251ca29f34622044ce703c5cebf30635b006affe1c7e496059f578dceb
|
|
| MD5 |
37c0ac53d242bd986c4483de3ba421e1
|
|
| BLAKE2b-256 |
c853fcf85ba5659ded33d86d1c9c69e01ad7cf473e9e7f0c781d9bf54a47b707
|
File details
Details for the file phani_aura_inspector-0.3.3-py3-none-any.whl.
File metadata
- Download URL: phani_aura_inspector-0.3.3-py3-none-any.whl
- Upload date:
- Size: 108.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8ba79c38c3ea0995ffb55f81f098bd4f839aa82c575644f5f0c3c3f9edcec50
|
|
| MD5 |
4c9209b918ca6f922dcd989227b2c1e3
|
|
| BLAKE2b-256 |
8fd2dc99f065e00c35bb816ff9b605ea015e3e3d8b460b3485f2ddc43a35b11b
|