Information
The Wildcard Dependency alert aims to give users greater visibility into packages that have dependencies with a floating version range. Wildcards are often used for convenience, and are especially common in open source projects and early-stage projects or fast-evolving environments, where developers aim to stay up-to-date with the latest features or bug fixes.
- Wildcards (*): A wildcard dependency allows any version of a package to be installed. For example, specifying "lodash": "*" in a package.json file will install the latest version of Lodash, no matter how new or different it is from prior versions. While this ensures you're always up-to-date, it also introduces risks by pulling in potentially unstable or breaking changes without your explicit review.
- Floating Dependency Ranges: Floating ranges allow for flexibility in the versions that can be installed. Instead of using a strict version, developers use operators like >, ^, or ~ to indicate compatibility within certain boundaries. For example, "lodash": "^4.0.0" means any version from 4.0.0 up to (but not including) 5.0.0 can be installed.
Some of the potential risks of Wildcard dependencies include the following:
- Unexpected Breakages: Minor updates can introduce bugs or break your app.
- Security Vulnerabilities: New versions may include vulnerabilities.
- Reproducibility: Harder to replicate environments consistently without locked versions.
- Unstable Dependencies: New updates may bring untested, unstable features.
- Dependency Conflicts: Floating versions can lead to incompatible updates.
- Silent Failures: Critical updates may fail quietly, leading to undetected issues.
- Delayed Issue Identification: Automatic updates can hide problems until they affect your app, complicating diagnosis.
Recommended actions
1. Use Exact Versions
- Recommendation: Specify exact versions for all dependencies.
- How: Use npm install <package>@<version> --save-exact or manually set versions in package.json.
- Why: Ensures reproducible builds and prevents unexpected changes.
2. Avoid Wildcards and Loose Versioning
- Avoid: *, >, >=, <, <=
- Why: These can lead to unpredictable updates and potential breaking changes.
3. Be Cautious with Caret (^) and Tilde (~) Ranges
- Caret (^): Allows updates to the most recent minor version.
- Tilde (~): Allows updates to the most recent patch version.
- Recommendation: Use these sparingly and understand their implications.
4. Use package-lock.json
- Why: Locks down all dependency versions, including nested dependencies.
- How: Commit package-lock.json to version control.
5. Semantic Versioning (SemVer)
- Understand and follow SemVer principles in your own packages.
- Respect SemVer when choosing version ranges for dependencies.
Examples
Here's an example of a package flagged for having a Wildcard dependency:
The alert links to where the dependency is listed in package.json
.
This is another example where a floating version range was flagged:
Detection Method
The Wildcard Dependency alert flags any package that has a dependency with a floating version range. It’s a medium-severity alert, because the behavior isn’t malicious but does introduce some security concerns. It flags any packages with dependencies that match the following:
- Wildcard * or empty string: Matches any version of a package, including untested or unstable versions.
- Greater than (>0 or >1): Installs any version above a certain threshold, which could pull in future versions with unknown changes or vulnerabilities.
In essence, these patterns are flagged because they allow for installing any version without strict control. Because wildcards can lead to unpredictable updates, they're often discouraged in critical systems. In these cases, you may want to update your security policy to monitor or warn.
Additional resources