JS 1.0 · Project evidence

JS Snippet (Plugin Installer): Find Vulnerabilities

Small Express plugin installer service with shell-based package installation.

Project purpose and scale

JS Snippet (Plugin Installer): Find Vulnerabilities

Small Express plugin installer service with shell-based package installation.

Source files
2
Reference findings
3
Matched signatures
10
Unmatched signatures
18

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
command-injectionhighapp.js:17jcl-command-injection-1
insecure-transportmediumapp.js:43jcl-insecure-transport-1
allocation-of-resources-without-limits-or-throttlingmediumapp.js:20jcl-no-rate-limit-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 Highcommand-injectionhighapp.js:175 of 5User-controlled plugin package data flows into child_process.spawn through a shell command.1
Claude Opus 4.6 Mediumcommand-injectionhighapp.js:175 of 5User-controlled plugin package data flows into child_process.spawn through a shell command.1
Claude Opus 4.7 Maxallocation-of-resources-without-limits-or-throttlingmediumapp.js:202 of 5The plugin installation endpoint performs expensive command execution without rate limiting.1
Claude Opus 4.7 Maxcommand-injectionhighapp.js:175 of 5User-controlled plugin package data flows into child_process.spawn through a shell command.1
Claude Sonnet 4.6 Highallocation-of-resources-without-limits-or-throttlingmediumapp.js:205 of 5The plugin installation endpoint performs expensive command execution without rate limiting.1
Claude Sonnet 4.6 Highcommand-injectionhighapp.js:175 of 5User-controlled plugin package data flows into child_process.spawn through a shell command.1
Claude Sonnet 4.6 Highinsecure-transportmediumapp.js:435 of 5The service is created with a plaintext HTTP server.1
Claude Sonnet 4.6 Mediumallocation-of-resources-without-limits-or-throttlingmediumapp.js:205 of 5The plugin installation endpoint performs expensive command execution without rate limiting.1
Claude Sonnet 4.6 Mediumcommand-injectionhighapp.js:175 of 5User-controlled plugin package data flows into child_process.spawn through a shell command.1
Claude Sonnet 4.6 Mediuminsecure-transportmediumapp.js:435 of 5The service is created with a plaintext HTTP server.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.6 Highinformation-exposuremediumapp.js:352 of 5The full stdout and stderr output from the spawned shell command is returned to the client in the JSON response. This can expose internal server paths, environment details, installed package versions, and other sensitive system information, especially when command injection is also possible.2
Claude Opus 4.7 Maxcsrfmediumapp.js:201 of 5State-changing POST endpoint /plugins/install has no CSRF protection or origin/authentication checks, allowing cross-site requests to trigger plugin installations.1
Claude Opus 4.7 Maximproper-type-validationlowapp.js:213 of 5req.body.package is used without type validation; a non-string value (object/array) could cause unexpected coercion or template interpolation behavior.3
Claude Opus 4.7 Maxinformation-exposurelowapp.js:353 of 5Raw stdout/stderr from the npm/shell child process is returned in the HTTP response, leaking internal filesystem paths, package manager errors, and other implementation details to clients.3
Claude Opus 4.7 Maxotherhighapp.js:201 of 5Missing authentication/authorization: the plugin install endpoint is fully unauthenticated, allowing any remote caller to trigger installation of arbitrary npm packages, which can execute install scripts and lead to remote code execution via malicious packages.1
Claude Sonnet 4.6 Highallocation-of-resources-without-limits-or-throttlingmediumapp.js:201 of 5The /plugins/install endpoint has no rate limiting. An attacker can flood it with requests to spawn many parallel npm processes, exhausting CPU, memory, and network resources (denial of service).1
Claude Sonnet 4.6 Highallocation-of-resources-without-limits-or-throttlingmediumapp.js:231 of 5The spawned child process has no timeout configured. A hanging or deliberately slow npm install can occupy a process slot and accumulate unbounded output in the 'output' buffer indefinitely, leading to resource exhaustion.1
Claude Sonnet 4.6 Highcommand-injectioncriticalapp.js:171 of 5runInstaller() passes the full command string to cp.spawn via 'sh -c', enabling shell interpretation of the entire command. This design pattern is inherently unsafe when any part of the command string derives from external input, as it is here.1
Claude Sonnet 4.6 Highcsrfhighapp.js:203 of 5The POST /plugins/install endpoint has no CSRF protection (no CSRF token, no Origin/Referer validation). A malicious third-party site can trigger plugin installations cross-site on behalf of a victim.3
Claude Sonnet 4.6 Highimproper-type-validationhighapp.js:211 of 5There is no validation that `req.body.package` is a string, matches a valid npm package-name format, or is restricted to an allowlist of permitted packages. Any value (including objects, arrays, or strings with shell metacharacters) is accepted and used directly in command construction.1
Claude Sonnet 4.6 Highinformation-exposurehighapp.js:355 of 5The full stdout and stderr output of the spawned shell process is collected and returned verbatim in the JSON response (`output` field). This can expose sensitive server-side information such as internal file paths, system configuration, environment details leaked by npm, and error messages that aid in reconnaissance.5
Claude Sonnet 4.6 Highothercriticalapp.js:204 of 5The `POST /plugins/install` endpoint has no authentication or authorization checks whatsoever. Any unauthenticated caller on the network can invoke it, which — combined with the command-injection vulnerability — provides trivially unauthenticated remote code execution.4
Claude Sonnet 4.6 Highpath-traversalhighapp.js:221 of 5Because packageName is user-controlled and unsanitized, an attacker can supply a 'file:' protocol package reference (e.g., 'file:../../../sensitive/dir') to npm install, causing npm to read from arbitrary filesystem paths outside the intended plugins directory.1
Claude Sonnet 4.6 Mediumallocation-of-resources-without-limits-or-throttlingmediumapp.js:261 of 5The output variable accumulates child-process stdout/stderr chunks without any size limit. A malicious or runaway process can produce unbounded output, exhausting heap memory.1
Claude Sonnet 4.6 Mediumcsrflowapp.js:202 of 5The state-changing POST /plugins/install endpoint has no CSRF token validation, allowing cross-site request forgery attacks in browser-accessible deployments.2
Claude Sonnet 4.6 Mediuminformation-exposuremediumapp.js:355 of 5The full stdout and stderr of the npm child process is returned to the caller. This may leak sensitive data such as absolute filesystem paths, npm registry tokens, or environment variable values from lifecycle scripts.5
Claude Sonnet 4.6 Mediumotherhighapp.js:203 of 5The /plugins/install endpoint has no authentication or authorization. Any unauthenticated network caller can trigger package installation or exploit the command injection vulnerability.3
Claude Sonnet 4.6 Mediumotherhighapp.js:211 of 5No input validation is performed on the package name. It should be validated against a strict allowlist or a regex matching valid npm package names before use in a shell command.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 High1110
Claude Opus 4.6 Medium1100
Claude Opus 4.7 Max2140
Claude Sonnet 4.6 High3381
Claude Sonnet 4.6 Medium3351

Inspectable source context

Reference locations

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

app.js:17jcl-command-injection-1

function runInstaller(command, options) {
  return cp.spawn(shell(), ["-c", command], options);
}
app.js:43jcl-insecure-transport-1
});

const server = http.createServer(app);
const port = process.env.PORT || 3000;
app.js:20jcl-no-rate-limit-1
}

app.post("/plugins/install", (req, res) => {
  const packageName = req.body.package || "@warehouse/scanner-bridge";
  const command = `npm install ${packageName} --prefix ${pluginRoot}`;

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