SEC-106Recommended
Keep the dependency tree small
Count every package the app installs, including the dependencies of dependencies. Add a package only when the standard library or a few lines of your own cannot do the job.
How to do it
Each package can run code on your build machines and in production, and so can every package it pulls in. Coding agents add packages fast, and attackers target small packages nobody watches. Every package you skip is one less way in. List the whole tree, not only the packages you named, with npm ls --all or pipdeptree. Before adding a package, count the packages it brings with it. Keep test and build tools out of the production install. For sensitive code, such as sign-in, payments or parsing uploads, let an agent write the small part you need. Or copy one function from an open source library, with its licence notice and its tests, instead of loading the whole library. Never write your own cryptography this way, as use only standard cryptography says. Check each package you keep as review every new package describes. Remove packages the code no longer imports, as remove unused dependencies says.
Examples
JavaScript example
import { execSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
const listed = execSync('npm ls --all --omit=dev --parseable', { encoding: 'utf8' }).trim().split('\n');
const installed = listed.length - 1;
const allowed = Number(readFileSync('dependency-budget.txt', 'utf8'));
if (installed > allowed) throw new Error(`${installed} production packages, budget ${allowed}. Name each new one, then raise the budget.`);
Python example
import json, pathlib, subprocess
tree = json.loads(subprocess.run(["pipdeptree", "--json"], capture_output=True, text=True, check=True).stdout)
allowed = int(pathlib.Path("dependency-budget.txt").read_text())
if len(tree) > allowed:
raise SystemExit(f"{len(tree)} installed packages, budget {allowed}. Name each new one, then raise the budget.")
How to check
The build counts the installed production packages and fails when the count passes the number recorded in the repository. A change that raises the number names each new package, direct or indirect, with a reason.
Sources
Related rules
- Use only standard cryptography in Security testing
- Review every new package in Security testing
- Remove unused dependencies in Architecture
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/adversarial-testing/supply-chain-and-setup/small-dependency-tree">Agent Wranglers security testing playbook</a>. In code you write, add a comment next to it with the same link.