NPM URL Dependency

ID

url_dependency_npm

Severity

low

Family

URL dependency

Tags

reachable

Description

This detector reports URL-based npm dependencies.

A URL-based dependency is fetched from a URL. See the "URLs as Dependencies" section in the npm documentation.

These dependencies are not fetched from the npm registry, so they are not immutable and could be changed by attackers to inject malicious code. In addition, the target resource could be removed.

In general, URL-based dependencies reduce the possibility for a reproducible build.

Security

Although versioning could be specified with tags encoded in the URL, tags could be changed to point to another snapshot of the target component, making the build potentially non-reproducible.

Additionally, an attacker with write permissions to the target resource could add malicious dependencies or inject unintended code.

Even though git tags should be always pointing to a commit and should not move once created, git allows a tag to be moved to a different commit (git tag --force my-tag <commit SHA> and git push --force --tags). Of course, branches are pointers to the commit history that move when changes are committed.

Examples

The following dependencies all use URLs in the version field. Npm allows shorthand URLs to GitHub projects with the syntax owner/project, like "expressjs/express".

package.json

 "dependencies": {
    "express": "expressjs/express",
    "mocha": "mochajs/mocha#4727d357ea",
    "module": "user/repo#feature/branch",

    "user-repo": "git://github.com/user/repo.git#ref",
    "user-repo-private": "git+ssh://git@github.com:user/repo.git#ref"
 }

Mitigation / Fix

If the package is owned by the organization, if possible, use a npm registry to publish versions of the package, with a scope like @myorg for your organization (a public registry or an internal one, depending on the intended visibility of the package).

For third-party packages, it is customary to have packages and published versions registered in a public npm registry (possibly wrapped by an internal registry for better control of the allowed dependencies). When possible, use a matching package version in the registry for the reported URL.

Remember to follow other security recommendations: use lockfiles for pinning versions, use scoped packages for internal software, use a npm configuration that ignore installation scripts when possible, etc.