const assignment = `obj[${JSON.stringify(key)}]=42`;
eval(assignment);
return obj;
}JS 1.0 · Project evidence
JS Snippet (Report Preview): Find Vulnerabilities
Small Express report preview service that builds saved dashboard metric objects.
Project purpose and scale
JS Snippet (Report Preview): Find Vulnerabilities
Small Express report preview service that builds saved dashboard metric objects.
- Source files
- 2
- Reference findings
- 2
- Matched signatures
- 6
- Unmatched signatures
- 19
Reference context
Deterministic reference findings
These findings define the project reference set for JS 1.0. Their presence does not establish exhaustive ground truth.
| Class | Severity | Location | Reference ID |
|---|---|---|---|
| code-injection | high | app.js:12 | jgl-code-injection-1 |
| improper-code-sanitization | medium | app.js:12 | jgl-improper-code-sanitization-1 |
Finding evidence
Reference-matched normalized signatures
Matched means agreement with the Snyk Code reference set, not independent ground-truth adjudication.
Severity and description show the deterministic most-frequent metadata variant; the final column records how many variants were observed across repetitions.
| Configuration | Class | Representative severity | Location | Recurrence | Representative description | Metadata variants |
|---|---|---|---|---|---|---|
| Claude Opus 4.6 High | code-injection | high | app.js:12 | 5 of 5 | User-controlled report metric data reaches eval and is executed as JavaScript code. | 1 |
| Claude Opus 4.6 Medium | code-injection | high | app.js:12 | 5 of 5 | User-controlled report metric data reaches eval and is executed as JavaScript code. | 1 |
| Claude Opus 4.7 Max | code-injection | high | app.js:12 | 5 of 5 | User-controlled report metric data reaches eval and is executed as JavaScript code. | 1 |
| Claude Sonnet 4.6 High | code-injection | high | app.js:12 | 5 of 5 | User-controlled report metric data reaches eval and is executed as JavaScript code. | 1 |
| Claude Sonnet 4.6 High | improper-code-sanitization | medium | app.js:12 | 1 of 5 | JSON.stringify is used as an attempted sanitizer before generated JavaScript is evaluated. | 1 |
| Claude Sonnet 4.6 Medium | code-injection | high | app.js:12 | 5 of 5 | User-controlled report metric data reaches eval and is executed as JavaScript code. | 1 |
Finding evidence
Unmatched normalized signatures
Unmatched reports may be false-positive-shaped, adjacent, or likely product-gap candidates.
Severity and description show the deterministic most-frequent metadata variant; the final column records how many variants were observed across repetitions.
| Configuration | Class | Representative severity | Location | Recurrence | Representative description | Metadata variants |
|---|---|---|---|---|---|---|
| Claude Opus 4.7 Max | allocation-of-resources-without-limits-or-throttling | low | app.js:6 | 1 of 5 | No rate limiting middleware is configured and no explicit JSON body size limit is set on express.json(). Combined with the eval-based code path, this increases exposure to CPU/memory abuse via crafted or repeated requests. | 1 |
| Claude Opus 4.7 Max | allocation-of-resources-without-limits-or-throttling | low | app.js:16 | 2 of 5 | The /reports/preview endpoint has no authentication and no rate limiting, allowing unbounded requests against an endpoint that invokes eval() — amplifying the impact of any code-injection weakness and enabling resource exhaustion. | 2 |
| Claude Opus 4.7 Max | improper-type-validation | medium | app.js:17 | 3 of 5 | req.body.metricKey is consumed without verifying it is a string or matches an allow-list of known metric identifiers. A client can submit objects, arrays, or other JSON types which are then serialized into the eval'd expression, leading to unexpected behavior. | 3 |
| Claude Sonnet 4.6 High | allocation-of-resources-without-limits-or-throttling | medium | app.js:16 | 4 of 5 | The `/reports/preview` POST endpoint has no rate-limiting, no request-per-second cap, and `express.json()` is configured without an explicit body-size limit. An unauthenticated attacker can send unlimited concurrent requests, exhausting CPU (via repeated `eval` calls) and memory, causing denial of service. | 4 |
| Claude Sonnet 4.6 High | allocation-of-resources-without-limits-or-throttling | medium | app.js:27 | 1 of 5 | No rate limiting or request throttling is applied to any route. The `/reports/preview` endpoint runs eval() on every request, making it computationally exploitable. Without throttling, the service is vulnerable to denial-of-service through request flooding. | 1 |
| Claude Sonnet 4.6 High | csrf | medium | app.js:16 | 1 of 5 | The POST `/reports/preview` endpoint has no CSRF token validation. Express provides no CSRF protection by default, so an attacker-controlled page can forge cross-origin POST requests on behalf of authenticated users. | 1 |
| Claude Sonnet 4.6 High | improper-type-validation | low | app.js:17 | 5 of 5 | metricKey is accepted from the request body without any type check, length constraint, or allowlist validation. Non-string types (objects, arrays, numbers, booleans) pass through to buildPreview and into JSON.stringify/eval, producing unexpected behaviour. | 5 |
| Claude Sonnet 4.6 High | information-exposure | medium | app.js:12 | 1 of 5 | eval(assignment) has no error handling. If the evaluated expression throws (e.g., due to malformed or unexpected-type input generating invalid JavaScript syntax), Express's default error handler will return a stack trace or internal error details to the client. | 1 |
| Claude Sonnet 4.6 High | prototype-pollution | high | app.js:10 | 2 of 5 | The user-supplied `metricKey` is used as an object property key inside eval() without filtering dangerous key names such as `__proto__`, `constructor`, or `prototype`. Sending `metricKey: "__proto__"` causes eval to execute `obj["__proto__"]=42`, modifying the object's prototype chain and potentially causing prototype pollution. | 2 |
| Claude Sonnet 4.6 High | prototype-pollution | medium | app.js:12 | 1 of 5 | When `metricKey` is `"__proto__"` or `"constructor"`, the eval'd expression becomes `obj["__proto__"]=42` or `obj["constructor"]=42`. Overwriting `constructor` on the returned object can corrupt downstream consumers that use the object's constructor reference, and could enable prototype-chain manipulation in combination with other gadgets in the application. | 1 |
| Claude Sonnet 4.6 Medium | allocation-of-resources-without-limits-or-throttling | medium | app.js:16 | 5 of 5 | The `POST /reports/preview` endpoint has no rate limiting. Each request invokes `eval()`, which is CPU-intensive. An unauthenticated attacker can flood the endpoint to exhaust server resources and cause a denial-of-service. | 5 |
| Claude Sonnet 4.6 Medium | csrf | low | app.js:16 | 3 of 5 | The state-changing POST /reports/preview endpoint has no CSRF protection (no token validation, no Origin/Referer check). If session cookies are used by clients, cross-site requests could trigger unintended actions. | 3 |
| Claude Sonnet 4.6 Medium | improper-type-validation | high | app.js:17 | 3 of 5 | `metricKey` is taken directly from the parsed JSON body with no type check, allowlist, or length limit. Any JSON type (object, array, number, null, string) is accepted and forwarded to the unsafe `eval()` call in `buildPreview()`, significantly expanding the attack surface for code injection and prototype pollution. | 3 |
| Claude Sonnet 4.6 Medium | information-exposure | medium | app.js:16 | 1 of 5 | There is no global error-handling middleware. Unhandled exceptions (e.g., from eval() failures) bubble up to Express's default error handler, which can return stack traces and internal file-system paths in the HTTP response body. | 1 |
| Claude Sonnet 4.6 Medium | information-exposure | low | app.js:23 | 1 of 5 | The `GET /reports/templates` endpoint exposes internal template names (`turnover`, `shortage`, `supplier-delay`) with no authentication. This aids reconnaissance by revealing the application's internal data model and business logic to unauthenticated users. | 1 |
| Claude Sonnet 4.6 Medium | other | low | app.js:5 | 1 of 5 | Missing security headers: only x-powered-by is disabled. No middleware such as Helmet.js is used, leaving responses without important headers like Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, etc. | 1 |
| Claude Sonnet 4.6 Medium | other | high | app.js:16 | 1 of 5 | Both API endpoints (`POST /reports/preview` and `GET /reports/templates`) require no authentication or authorization. Any unauthenticated user or external attacker can invoke the code-execution path via `/reports/preview` without presenting any credentials, token, or session. | 1 |
| Claude Sonnet 4.6 Medium | other | low | app.js:17 | 1 of 5 | No authentication or authorization is enforced on either endpoint (/reports/preview and /reports/templates). Any unauthenticated client on the network can invoke these APIs, including triggering the eval() code path. | 1 |
| Claude Sonnet 4.6 Medium | prototype-pollution | high | app.js:12 | 1 of 5 | The eval'd expression `obj[<user-key>]=42` allows an attacker to send `metricKey: "__proto__"` or `metricKey: "constructor"`, causing eval to execute `obj["__proto__"]=42`, which pollutes `Object.prototype` and can corrupt the prototype chain for all objects in the process, potentially bypassing security checks throughout the application. | 1 |
Model behavior
Recurrence by configuration
Stable recurrence measures repeated behavior, not independent validity.
| Configuration | Matched signatures | Matched all five | Unmatched signatures | Unmatched all five |
|---|---|---|---|---|
| Claude Opus 4.6 High | 1 | 1 | 0 | 0 |
| Claude Opus 4.6 Medium | 1 | 1 | 0 | 0 |
| Claude Opus 4.7 Max | 1 | 1 | 3 | 0 |
| Claude Sonnet 4.6 High | 2 | 1 | 7 | 1 |
| Claude Sonnet 4.6 Medium | 1 | 1 | 9 | 1 |
Inspectable source context
Reference locations
Apache-licensed fixture excerpts are shown around declared reference lines. They are evidence, not runnable examples.
const assignment = `obj[${JSON.stringify(key)}]=42`;
eval(assignment);
return obj;
}Interpretation boundary
Inspect divergence before classifying it
Unmatched reports may be false-positive-shaped, adjacent to the release reference scope, or likely valid product-gap candidates. Missed reference findings may expose representative-versus-systematic coverage behavior.
Return to explorer evidence