npq

repository·main·Indexed 23 days ago

https://github.com/lirantal/npq

A security auditing tool for npm packages that allows developers to inspect for vulnerabilities and suspicious patterns before installation. It uses a system of 'Marshalls' to validate package age, signatures, provenance, Snyk vulnerabilities, typosquatting, and more. npq can be integrated into CI/CD pipelines or used as a wrapper for package managers like npm, yarn, or pnpm to ensure every installation is automatically audited.

Tokens
19.5K
Snippets
35
Records
110
Agent score
78%

What's inside npq

  1. What is the Age Marshall and how does it work?

    main

    The Age Marshall is a security validation component in NPQ that belongs to the PackageHealth category. It analyzes package age and maturity to identify potential supply chain risks by performing two primary checks:

    1. New Package Detection: Flags packages that are too new (less than 22 days old) to prevent installation of potentially malicious or typosquatting packages that haven't undergone community review.
    2. Abandoned Package Detection: Warns about packages that appear unmaintained (versions older than 365 days) to alert users to potentially unpatched security vulnerabilities.

    It works by fetching metadata from the npm registry and analyzing the time.created (package creation) and time[version] (version release) fields using millisecond precision.

  2. Dormant maintainer check rules and thresholds

    main

    The Dormant maintainer check flags when a publishing user (matched by _npmUser.email) has a previous release on this package, followed by a long calendar gap before the current release.

    How the gap is measured: npq looks for the latest version in the package metadata that was published by the same email strictly before the current version. The gap is the difference in whole days between those two timestamps.

    Rules:

    • Gap > 274 days (~9 months): Throws an Error ("more than 9 months dormant").
    • Gap > 183 days (~6 months): Throws a Warning ("more than 6 months dormant").
    • Note: If the email has no prior history on this package, this check is skipped.
    • Note: Other maintainers publishing in the gap does not reset the timer for this specific email; only versions with the same email count toward the gap calculation.
  3. Use npq as a transparent package manager alias

    main

    You can use npq-hero as a transparent drop-in replacement for your package manager (e.g., npm, yarn, pnpm). When aliased, npq-hero intercepts install commands to run security checks (marshalls) before handing off to the real package manager. All other commands (like npm test or npm audit) are passed through untouched, ensuring your existing workflows remain unchanged.

    There are two distinct binaries:

    • npq: A standalone CLI for explicit, on-demand use with its own flags (--dry-run, --plain, etc.).
    • npq-hero: A wrapper designed for aliasing. It has no CLI flags of its own to prevent conflicts with the underlying package manager's flags.
  4. Security: No public-registry fallback

    main
    To prevent incorrect audit results and avoid disclosing private package names to public services, NPQ never falls back to registry.npmjs.org or the public npm downloads service for a package that has been assigned to a custom registry. All metadata, manifests, signing keys, and attestations are retrieved strictly from the selected registry context.
  5. How the Auto-Continue feature works

    main

    The auto-continue feature streamlines package installation by automatically proceeding after a countdown when security audits detect warnings but no errors.

    Activation Criteria:

    1. The security audit completes with at least one warning and zero errors.
    2. The user has not explicitly disabled the feature.

    If no issues are found, installation proceeds immediately. If errors are found, npq will prompt for manual confirmation instead of using a countdown.

    Default Behavior:

    • Duration: 15 seconds.
    • Interaction: You can press y or Y during the countdown to skip the timer and install immediately. Pressing Ctrl+C will abort the installation with exit code 1.
  6. Age Marshall security implications and limitations

    main

    While the Age Marshall mitigates certain risks, developers should be aware of its limitations:

    Risk Mitigation

    • Supply Chain Attacks: Flags new packages for manual review.
    • Typosquatting: Catches recently created packages with suspicious names.
    • Abandoned Packages: Identifies potentially unmaintained software.

    Limitations

    • False Positives: Legitimate new packages will be flagged.
    • Bypass Potential: Attackers can bypass detection by waiting 22 days before publishing malicious updates.
    • Maintenance Assumption: Package age is a proxy for security and does not guarantee active maintenance or safety.
  7. Understand NPQ configuration precedence

    main

    NPQ follows standard npm configuration precedence. If multiple sources define a setting, the highest priority wins. Scoped registries (e.g., @company:registry) are selected independently of the unscoped default registry.

    1. Command-line options (e.g., `--registry`)
    2. `npm_config_*` environment variables
    3. Project `.npmrc`
    4. User `.npmrc`
    5. Global npm configuration
    6. The public npm registry default
  8. Understand how npq handles registry capabilities and 'notEvaluated' results

    main

    When using custom registries, some security features (like signing keys or provenance attestations) might not be available. npq distinguishes between a failed connection and an unavailable capability.

    Unavailable Capabilities (notEvaluated)

    If a registry endpoint for an optional service (like signing keys) returns 404, 405, or 501, or if the response indicates the capability is absent, npq marks the check as notEvaluated.

    • notEvaluated results appear in output but do not increment warning/error counts.
    • They do not change the process exit status.
    • They do not trigger prompts or auto-continue.

    Registry Failures (Audit Stops)

    The audit will stop and report an error (rather than notEvaluated) if it encounters:

    • Authentication/Authorization failures (401, 403).
    • TLS, proxy, certificate, DNS, timeout, or connection failures.
    • Registry server failures.
    • Malformed core package metadata.
    • Invalid npm configuration.
  9. How malicious packages are identified by data sources

    main

    The criteria for marking a package as 'malicious' depend on the active data source:

    Snyk API

    A package is malicious if any vulnerability in the response has: vulnerability.title === "Malicious Package"

    OSV API

    A package is malicious if any vulnerability matches either of these conditions:

    1. database_specific["malicious-packages-origins"]: If this property exists and is an array (even an empty one).
    2. summary prefix: If the summary string, when lowercased, starts with "malicious" (e.g., "Malicious code in...").
  10. Understand the expired-domain maintainer identity warning format

    main

    When npq detects an expired domain (where DNS resolution fails and RDAP shows no active registration), it provides a corroborated warning. The warning includes a summary sentence followed by an Affected maintainers: section.

    This section lists affected domains in lexical order. For each domain, it lists the associated maintainer identities in their registry order using the format name <email>. If a maintainer does not have a usable name, only the <email> is rendered.

    Note that invalid email records are excluded from this identity list but are still counted as incomplete records under existing policies.

    Maintainer domain example.com does not resolve in public DNS, and RDAP found no active registration; account takeover may be possible.
    
    Affected maintainers:
    - example.com: Alice Smith <alice@example.com>, Bob Jones <bob@example.com>
  11. How the expired-domain marshall works

    main

    The expired-domain marshall is a warning-only signal that identifies a potential account-recovery risk. It checks if a package maintainer's email domain no longer resolves and has no active registration in authoritative RDAP data.

    Logic and Scope

    • Targeting: It only evaluates simple two-label domains (e.g., example.com).
    • Exclusions: Multipart domains (e.g., example.co.uk), IP literals, special-use domains, single-label names, and internal names are not evaluated.
    • Process:
      1. Converts maintainer email hosts to ASCII and lowercases them.
      2. Checks if the domain resolves via public DNS.
      3. If the domain does not resolve (NXDOMAIN) and the TLD is verifiable, it queries the authoritative RDAP service.

    Evidence Levels and Results

    EvidenceResult
    Public DNS resolvesPass; RDAP is not queried
    A multipart domain returns NXDOMAINNot evaluated; RDAP is not queried
    A simple domain returns NXDOMAIN but its top-level domain cannot be verifiedNot evaluated; RDAP is not queried
    A simple domain returns NXDOMAIN, its top-level domain resolves, and RDAP returns a registered domain objectPass; the DNS-only warning is suppressed
    A simple domain returns NXDOMAIN, its top-level domain resolves, and the authoritative RDAP service returns 404Warning that no active registration was found and account takeover may be possible
    DNS is inconclusive, RDAP cannot be routed, times out, rate-limits, or returns invalid dataNot evaluated

    Important Limitations

    • Non-blocking: Warnings do not block installation.
    • No Proof of Purchase: An RDAP 404 does not guarantee a domain is purchasable; registry policies may prevent registration.
    • Security Context: The check cannot determine if npm 2FA is enabled or if the email is specifically used for account recovery.
  12. Understand npq-hero command interception and exit codes

    main

    Command Interception

    npq-hero detects install commands (including install, i, add, and common misspellings like isntall) to trigger security marshalls. All other commands (e.g., audit, test, run, ls, why, outdated) are treated as passthroughs. For passthroughs, npq-hero runs an empty marshall pipeline and immediately spawns the real package manager.

    Exit Code Preservation

    npq-hero preserves the exit code of the underlying package manager. This is critical for CI/CD pipelines. If a command like npm audit returns a non-zero exit code, npq-hero will propagate that same code.

    ScenarioExit Code
    npm install express succeeds0
    npm audit finds vulnerabilities1
    npm run build failsnon-zero (whatever the script returns)
    User aborts at the npq prompt (Ctrl+C)1
    npq encounters an internal error-1
    Unsupported Node version (with npq)-1