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.

ClassSeverityLocationReference ID
code-injectionhighapp.js:12jgl-code-injection-1
improper-code-sanitizationmediumapp.js:12jgl-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.

ConfigurationClassRepresentative severityLocationRecurrenceRepresentative descriptionMetadata variants
Claude Opus 4.6 Highcode-injectionhighapp.js:125 of 5User-controlled report metric data reaches eval and is executed as JavaScript code.1
Claude Opus 4.6 Mediumcode-injectionhighapp.js:125 of 5User-controlled report metric data reaches eval and is executed as JavaScript code.1
Claude Opus 4.7 Maxcode-injectionhighapp.js:125 of 5User-controlled report metric data reaches eval and is executed as JavaScript code.1
Claude Sonnet 4.6 Highcode-injectionhighapp.js:125 of 5User-controlled report metric data reaches eval and is executed as JavaScript code.1
Claude Sonnet 4.6 Highimproper-code-sanitizationmediumapp.js:121 of 5JSON.stringify is used as an attempted sanitizer before generated JavaScript is evaluated.1
Claude Sonnet 4.6 Mediumcode-injectionhighapp.js:125 of 5User-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.

ConfigurationClassRepresentative severityLocationRecurrenceRepresentative descriptionMetadata variants
Claude Opus 4.7 Maxallocation-of-resources-without-limits-or-throttlinglowapp.js:61 of 5No 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 Maxallocation-of-resources-without-limits-or-throttlinglowapp.js:162 of 5The /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 Maximproper-type-validationmediumapp.js:173 of 5req.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 Highallocation-of-resources-without-limits-or-throttlingmediumapp.js:164 of 5The `/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 Highallocation-of-resources-without-limits-or-throttlingmediumapp.js:271 of 5No 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 Highcsrfmediumapp.js:161 of 5The 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 Highimproper-type-validationlowapp.js:175 of 5metricKey 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 Highinformation-exposuremediumapp.js:121 of 5eval(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 Highprototype-pollutionhighapp.js:102 of 5The 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 Highprototype-pollutionmediumapp.js:121 of 5When `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 Mediumallocation-of-resources-without-limits-or-throttlingmediumapp.js:165 of 5The `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 Mediumcsrflowapp.js:163 of 5The 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 Mediumimproper-type-validationhighapp.js:173 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 Mediuminformation-exposuremediumapp.js:161 of 5There 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 Mediuminformation-exposurelowapp.js:231 of 5The `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 Mediumotherlowapp.js:51 of 5Missing 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 Mediumotherhighapp.js:161 of 5Both 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 Mediumotherlowapp.js:171 of 5No 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 Mediumprototype-pollutionhighapp.js:121 of 5The 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.

ConfigurationMatched signaturesMatched all fiveUnmatched signaturesUnmatched all five
Claude Opus 4.6 High1100
Claude Opus 4.6 Medium1100
Claude Opus 4.7 Max1130
Claude Sonnet 4.6 High2171
Claude Sonnet 4.6 Medium1191

Inspectable source context

Reference locations

Apache-licensed fixture excerpts are shown around declared reference lines. They are evidence, not runnable examples.

app.js:12jgl-code-injection-1
  const assignment = `obj[${JSON.stringify(key)}]=42`;

  eval(assignment);
  return obj;
}
app.js:12jgl-improper-code-sanitization-1
  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