Skip to content

Repository files navigation

MoppScan

Prototype-pollution research with evidence you can trust.

CI Security Python 3.10–3.13 MIT License MCP 2.x

MoppScan confirms client-side prototype-pollution sources in a real browser, helps researchers investigate gadget impact, fingerprints known risky JavaScript components, and provides separately gated server-side probes. Its default is intentionally simple:

moppscan https://app.example.com/search?q=test

That command tests the supplied page. It does not crawl the whole domain, drive exploit gadgets, weaken browser security policy, or run server-side probes.

Use MoppScan only on systems you own or are explicitly authorized to test.

Install the preview

MoppScan currently supports Python 3.10–3.13. Until the first signed PyPI release, install it from the CodeJavu repository:

git clone https://github.com/codejavu-llc/moppscan.git
cd moppscan
python -m venv .venv
source .venv/bin/activate
python -m pip install -e .
moppscan doctor --fix

doctor launches a tiny local browser check and tells you exactly what is missing. It also supports --json for automated setup validation.

The researcher workflow

Start with the focused scan, then deepen only the confirmed leads:

# 1. Confirm attacker-reachable query/hash pollution on one page
moppscan https://app.example.com/page?id=1

# 2. Fast canary sweep from stdin or a file
cat urls.txt | moppscan scan --only-vuln
moppscan scan -l urls.txt --only-vuln --json -o findings.json

# 3. Explicitly investigate gadget execution and save evidence
moppscan exploit https://app.example.com/page?id=1 \
  --confirm --screenshots ./evidence

# 4. Passive component and version candidates
moppscan sca https://app.example.com

# 5. Separately authorized server-side differential probes
moppscan sspp https://api.example.com/merge --confirm -X POST \
  -d '{"name":"test"}'

For authenticated targets, reuse a Playwright storage-state file or pass headers/cookies:

moppscan https://app.example.com/account \
  --storage-state session.json

moppscan https://app.example.com/account \
  -H 'Authorization: Bearer …' --cookie 'session=…'

Treat storage-state files, cookies, and authorization headers as secrets. Do not commit them.

For automation, add --json. Full single-target reports declare schema_version: 1.0.0 and validate against the JSON Schema shipped in moppscan/schemas/report-v1.schema.json. Status stays on stderr, so stdout can be piped safely.

Evidence, not vibes

MoppScan separates technical signals that many scanners blur together:

Evidence level Meaning Report-ready?
candidate A passive match or unconfirmed runtime signal. No
component_source / component_impact A loaded component behaved unsafely when invoked directly, but attacker reachability was not proven. No
confirmed_source A unique key/value canary reached Object.prototype through the supplied target input. Usually needs impact
confirmed_impact The attacker-reachable path executed MoppScan's unique tagged proof. Strong evidence

A page's own dialog, a library filename, a candidate source→gadget pairing, a controlled sink value, or a script element that CSP prevents from executing is never promoted to confirmed impact.

Deliberate depth

Broad discovery and experimental analysis remain available without making the first command surprising:

# Discover and bound candidates, confirm sources, then run passive SCA
moppscan all example.com --max-urls 100 --max-per-host 30

# Add bounded crawling plus static and heuristic analysis
moppscan https://app.example.com --deep --depth 2 --max-pages 20

# Active deep research is an explicit decision
moppscan https://app.example.com --deep --gadgets \
  --screenshots ./evidence

TLS verification, CSP, X-Frame-Options, same-origin policy, and browser site isolation remain enabled. -k/--insecure is an explicit exception for an authorized target with an untrusted certificate.

MCP for AI-assisted research

The optional MCP server lets an AI client search the local catalog, triage passive component candidates, and run tightly scoped canary checks. It uses local stdio; there is no listener or cloud service.

python -m pip install -e '.[mcp]'
moppscan-mcp --version

Safe, catalog-only configuration:

{
  "mcpServers": {
    "moppscan": {
      "command": "moppscan-mcp"
    }
  }
}

Allow passive network access to one target:

{
  "mcpServers": {
    "moppscan": {
      "command": "moppscan-mcp",
      "args": ["--allow-host", "app.example.com"]
    }
  }
}

Client canary scans additionally need the human-controlled --allow-active startup flag. SSPP needs --allow-active --allow-sspp. Private and loopback targets also need an exact host rule and --allow-private. A model-provided confirmation value is never the primary security boundary.

See MCP integration and the threat model before enabling network tools.

Output

  • Default/TSV keeps one finding per line for shell pipelines.
  • --json is the structured automation boundary.
  • --md creates a concise, reviewable write-up.
  • scan -f html creates a self-contained evidence report.
  • Status goes to stderr; findings go to stdout or -o.

Scans exit 0 after a completed run by default. Use --fail-on confirmed-source or --fail-on confirmed-impact to exit 3 when that verified evidence threshold is reached. Usage errors exit 2; execution failures exit 1. Candidates never trigger a findings exit by themselves.

URLs shown to MCP clients are bounded and redact credentials/query values.

Why this project exists

Existing tools cover important parts of the problem: PortSwigger DOM Invader offers an excellent Burp-native workflow; ppfuzz, ppmap, and pphack make bulk client checks accessible; Silent Spring, Dasty, GHunter, ProbeTheProto, and GALA advance program analysis and gadget research. MoppScan's goal is the open-source bridge between those worlds: approachable on the first run, automation-friendly at scale, and strict enough that researchers can trust what a result actually proves.

The research comparison, product principles, benchmarks, and staged plan are in Research roadmap.

Contributing

New payload or gadget entries need a primary reference, provenance, a local positive fixture, and a negative control. Detection breadth without a truth test does not merge.

python -m pip install -e '.[dev,mcp,security]'
moppscan doctor
ruff check moppscan tests
pytest
python -m build
python -m twine check dist/*

Read Contributing, Architecture, Security policy, Credits, and the Changelog.

License

MIT. The license permits use and modification of the software; it does not grant authorization to test third-party systems.

About

Evidence-first prototype pollution scanner with safe client, server, SCA, and MCP workflows

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages