Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions skills/appsec/dependency-scanning/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,49 @@ Direct dependencies are explicitly declared. Transitive dependencies are pulled
- Pin critical transitive dependencies using overrides/resolutions (`npm overrides`, `pip` constraints files, `go.mod replace`).
- Evaluate dependency tree depth before adopting new packages: `npm ls --all`, `pipdeptree`, `go mod graph`.

## Override and Replacement Governance

Overrides, resolutions, constraints, `replace` directives, and `[patch]` sections are powerful supply-chain controls. They can safely pin a vulnerable transitive package to a fixed version, but they can also redirect a trusted package name to an unreviewed fork, mutable branch, local path, stale constraint, or vulnerable downgrade. Review them as dependency-graph rewrites, not as automatically safe mitigations.

### Mechanisms to Inspect

| Ecosystem | Mechanism | Files to Review |
|---|---|---|
| npm | `overrides` | `package.json`, `package-lock.json`, `npm-shrinkwrap.json` |
| Yarn | `resolutions` | `package.json`, `yarn.lock` |
| pnpm | `pnpm.overrides` | `package.json`, `pnpm-lock.yaml`, workspace manifests |
| Go | `replace` | `go.mod`, `go.sum`, release build metadata |
| Rust | `[patch.crates-io]` / `[replace]` | `Cargo.toml`, `Cargo.lock` |
| Maven / Gradle | dependency management, constraints, substitutions | `pom.xml`, `build.gradle`, lockfiles |
| Python | constraints, alternate indexes, direct URLs | `constraints.txt`, `requirements.txt`, lockfiles |

### Evidence Gates

```
DEP-OVERRIDE-01: Override/replacement has no documented reason, owner, approval, or review date
DEP-OVERRIDE-02: Override/resolution/constraint forces a version below the fixed or vendor-recommended safe version
DEP-OVERRIDE-03: Registry dependency is redirected to an unpinned git URL, mutable branch/tag, local path, alternate registry, or unreviewed fork
DEP-OVERRIDE-04: Manifest override is not reflected in the committed lockfile or SBOM relationship data
DEP-OVERRIDE-05: Temporary override has no expiry, upstream tracking issue, or re-evaluation trigger
DEP-OVERRIDE-06: Development-only local path replacement appears in production or release artifact build inputs
DEP-OVERRIDE-07: Scanner/SBOM evidence covers the original package name but not the resolved replacement artifact
```

### False-Positive Boundaries

- Do not flag a fixed-version override that pins a vulnerable transitive dependency to a patched version from the same trusted registry when the lockfile, owner approval, reason, and review trigger are present.
- Do not flag workspace path replacements used only for local development unless they are included in production build inputs, release artifacts, or deployment lockfiles.
- Do not treat every Go `replace` or Rust `[patch]` directive as malicious; classify by source trust, immutable pinning, build context, and approval evidence.
- Do not credit an override as a mitigation if it is missing from the lockfile/SBOM, downgrades below the fixed version, or masks an upstream update without a removal plan.

### Review Steps

1. Locate override controls in manifests, lockfiles, package-manager config, and workspace files.
2. Compare each target version/source with known fixed versions, vendor advisories, and scanner output.
3. Verify the lockfile and SBOM represent the final resolved artifact, not just the original package name.
4. Require immutable source references for git replacements (commit SHA preferred; branches and tags require extra verification and protection evidence).
5. Record owner, reason, approval, lockfile evidence, and expiry/review trigger for each production override.

## Vulnerability Triage: EPSS + CVSS + CISA KEV

### Triage Framework
Expand Down Expand Up @@ -212,12 +255,19 @@ When performing a dependency scan, produce findings in the following structure:
- [ ] Packages with install scripts
- [ ] Unmaintained packages (no release in 2+ years)
- [ ] Dependency confusion risk (internal name collisions)
- [ ] Override/replacement directives present

### Recommendations

1. [Prioritized list of remediation actions]
```

### Override / Replacement Review

| Package | Ecosystem | Mechanism | Original Source | Replacement Source | Resolved Version / Commit | Lockfile / SBOM Evidence | Owner / Rationale | Expiry / Review Trigger | Disposition |
|---|---|---|---|---|---|---|---|---|---|
| [package] | [npm/Go/Rust/etc.] | [override/replace/patch/constraint] | [registry/version] | [version, registry, git SHA, path] | [resolved artifact] | [present/missing] | [owner/reason] | [date/issue] | [Mitigation / Monitor / Finding] |

## Procedure

1. **Identify manifests**: Use Glob to locate all package manifest and lockfiles in the project.
Expand All @@ -226,8 +276,9 @@ When performing a dependency scan, produce findings in the following structure:
4. **Vulnerability scan**: Cross-reference packages and versions against known CVE databases. Apply the EPSS+CVSS+KEV triage model.
5. **License audit**: Extract license declarations from lockfiles or registry metadata. Flag copyleft and unlicensed packages.
6. **Typosquatting check**: Review dependency names for patterns described in the detection section.
7. **Supply chain assessment**: Evaluate SLSA posture -- lockfile presence, pinned versions, provenance availability.
8. **Report**: Produce the assessment using the output template above, with prioritized remediation recommendations.
7. **Override/replacement review**: Inspect overrides, resolutions, constraints, Go `replace`, Rust `[patch]`, Maven/Gradle substitutions, and Python direct URLs for source provenance, fixed-version safety, owner approval, expiry, and lockfile/SBOM consistency.
8. **Supply chain assessment**: Evaluate SLSA posture -- lockfile presence, pinned versions, provenance availability.
9. **Report**: Produce the assessment using the output template above, with prioritized remediation recommendations.

## Prompt Injection Safety Notice

Expand All @@ -251,3 +302,8 @@ This skill processes user-supplied content including package manifests, lockfile
- [NIST NVD](https://nvd.nist.gov/)
- [OpenSSF Scorecard](https://securityscorecards.dev/)
- [Executive Order 14028 - Improving the Nation's Cybersecurity](https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/)
- [npm package overrides](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#overrides)
- [Yarn selective dependency resolutions](https://yarnpkg.com/features/resolutions)
- [pnpm overrides](https://pnpm.io/package_json#pnpmoverrides)
- [Go modules replace directive](https://go.dev/ref/mod#go-mod-file-replace)
- [Cargo overriding dependencies](https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html)
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Benign: Governed fixed-version overrides and development-only replacements

This fixture should avoid false positives where override controls are documented, reflected in lockfiles, and scoped safely.

## npm package.json

```json
{
"dependencies": {
"webpack": "5.91.0"
},
"overrides": {
"braces": "3.0.3"
}
}
```

## package-lock excerpt

```json
{
"packages": {
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-example"
}
}
}
```

Expected outcome: treat the `braces` override as a governed mitigation, not a finding, when the advisory fixed version is `3.0.3`, the package remains on the same trusted registry, and the lockfile reflects the resolved artifact.

## Go development-only replacement

```go
module example.com/orders

require github.com/acme/shared v1.4.2

// Used only by local integration tests; release workflow checks that no replace directives remain.
replace github.com/acme/shared => ../shared
```

Governance evidence:

- Owner: platform security
- Reason: local integration-test workspace
- Production release check: CI step `go list -m -json all` fails release builds when `Replace` is non-null
- SBOM evidence: release SBOM records `github.com/acme/shared v1.4.2` from the public module proxy
- Review trigger: remove when shared test harness publishes v1.4.3

Expected outcome: monitor or document the local replacement, but do not classify it as a production finding when release evidence proves it is excluded from production artifacts.

## Rust pinned patch

```toml
[dependencies]
ring = "0.17"

[patch.crates-io]
ring = { git = "https://github.com/org-reviewed/ring", rev = "7f3a0d9b6e1f2c3a4b5c6d7e8f90123456789abc" }
```

Governance evidence:

- Owner: crypto platform lead
- Reason: temporary FIPS validation patch before upstream release
- Review date: 2026-06-01
- Expiry: remove after upstream `ring` release includes patch or by 2026-07-15
- Lockfile evidence: `Cargo.lock` records the exact git revision
- Scanner/SBOM evidence: SBOM component includes the replacement URL and commit

Expected outcome: classify as governed/monitor, not a high-risk unpinned fork, because the source is reviewed, pinned to an immutable revision, reflected in the lockfile/SBOM, and time-bounded.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Vulnerable: Ungoverned dependency override and replacement rewrites

This fixture should produce override/replacement governance findings.

## npm package.json

```json
{
"dependencies": {
"lodash": "^4.17.21",
"minimist": "^1.2.8"
},
"overrides": {
"lodash": "github:unknown-user/lodash#main",
"**/minimist": "0.0.8"
}
}
```

Expected findings:

- `DEP-OVERRIDE-02` because the `minimist` resolution forces a vulnerable downgrade below known fixed lines.
- `DEP-OVERRIDE-03` because `lodash` is redirected from the public registry to an unreviewed git source on a mutable `main` branch.
- `DEP-OVERRIDE-04` if the lockfile or SBOM does not show the final git artifact and downgraded minimist package.

## Go go.mod

```go
module example.com/payments

require github.com/acme/auth v1.8.4

replace github.com/acme/auth => ../auth
replace github.com/acme/payments => github.com/fork/payments v0.0.0-20260601000000-deadbeef
```

Expected findings:

- `DEP-OVERRIDE-03` for a forked replacement without owner/provenance review.
- `DEP-OVERRIDE-06` if the local `../auth` replacement is present in production or release artifact build inputs.

## Rust Cargo.toml

```toml
[dependencies]
ring = "0.17"

[patch.crates-io]
ring = { git = "https://github.com/example/ring", branch = "main" }
```

Expected findings:

- `DEP-OVERRIDE-03` because the trusted crates.io package is shadowed by a git source.
- `DEP-OVERRIDE-05` if there is no removal plan, upstream tracking issue, or re-evaluation trigger.

## Governance Evidence

- Owner approval: absent
- Security rationale: "temporary build fix"
- Review date: absent
- Expiry/review trigger: absent
- Lockfile/SBOM evidence: unavailable
- Scanner output: covers package names only, not resolved replacement artifacts

Expected outcome: classify as supply-chain findings, not as ordinary safe transitive-dependency mitigations.