|
| 1 | +--- |
| 2 | +title: 'Dependency Scanning Fundamentals' |
| 3 | +description: 'Understand how dependency scanning works, vulnerability databases, severity scoring, and the difference between direct and transitive dependencies.' |
| 4 | +--- |
| 5 | + |
| 6 | +Before diving into specific tools, you need to understand how dependency scanning works and the ecosystem that powers it. This knowledge helps you interpret scan results, prioritize fixes, and configure tools effectively. |
| 7 | + |
| 8 | +## How Dependency Scanning Works |
| 9 | + |
| 10 | +Dependency scanners follow a consistent process: |
| 11 | + |
| 12 | +``` |
| 13 | +1. Parse Lock Files |
| 14 | + package-lock.json, Pipfile.lock, pom.xml → Dependency Graph |
| 15 | +
|
| 16 | +2. Query Vulnerability Databases |
| 17 | + Dependency versions → CVE/advisory lookup → Matches |
| 18 | +
|
| 19 | +3. Generate Report |
| 20 | + Vulnerable packages + severity + remediation advice |
| 21 | +``` |
| 22 | + |
| 23 | +**Key insight**: Scanners don't analyze your code—they compare your dependency versions against known vulnerability databases. This makes scanning fast but means zero-day vulnerabilities won't be detected until they're catalogued. |
| 24 | + |
| 25 | +## Vulnerability Databases |
| 26 | + |
| 27 | +Multiple databases track known vulnerabilities: |
| 28 | + |
| 29 | +| Database | Scope | Maintained By | |
| 30 | +|----------|-------|---------------| |
| 31 | +| **NVD** (National Vulnerability Database) | All software | NIST (US Government) | |
| 32 | +| **GitHub Advisory Database** | Open source packages | GitHub + Community | |
| 33 | +| **OSV** (Open Source Vulnerabilities) | Open source | Google | |
| 34 | +| **Snyk Vulnerability DB** | Open source + containers | Snyk | |
| 35 | +| **npm Advisory Database** | JavaScript/Node.js | GitHub (formerly npm) | |
| 36 | +| **PyPI Advisory Database** | Python | Python Packaging Authority | |
| 37 | + |
| 38 | +Most tools aggregate multiple databases. Snyk and GitHub maintain their own curated databases with additional context and fix recommendations. |
| 39 | + |
| 40 | +## Understanding CVEs and Severity |
| 41 | + |
| 42 | +### CVE Identifiers |
| 43 | + |
| 44 | +CVE (Common Vulnerabilities and Exposures) provides unique identifiers for vulnerabilities: |
| 45 | + |
| 46 | +``` |
| 47 | +CVE-2021-44228 (Log4Shell) |
| 48 | + | | | |
| 49 | + | | +-- Sequential number |
| 50 | + | +------ Year discovered/published |
| 51 | + +---------- CVE prefix |
| 52 | +``` |
| 53 | + |
| 54 | +### CVSS Scoring |
| 55 | + |
| 56 | +CVSS (Common Vulnerability Scoring System) rates severity from 0.0 to 10.0: |
| 57 | + |
| 58 | +| Score | Severity | Action | |
| 59 | +|-------|----------|--------| |
| 60 | +| 9.0 - 10.0 | **Critical** | Fix immediately | |
| 61 | +| 7.0 - 8.9 | **High** | Fix within days | |
| 62 | +| 4.0 - 6.9 | **Medium** | Fix within weeks | |
| 63 | +| 0.1 - 3.9 | **Low** | Fix when convenient | |
| 64 | + |
| 65 | +**CVSS v3.1 example** (Log4Shell): |
| 66 | + |
| 67 | +``` |
| 68 | +Base Score: 10.0 (Critical) |
| 69 | +
|
| 70 | +Attack Vector: Network (remotely exploitable) |
| 71 | +Attack Complexity: Low (easy to exploit) |
| 72 | +Privileges Required: None |
| 73 | +User Interaction: None |
| 74 | +Impact: Complete system compromise |
| 75 | +``` |
| 76 | + |
| 77 | +### Beyond CVSS: Exploitability |
| 78 | + |
| 79 | +CVSS alone doesn't tell the whole story. Consider: |
| 80 | + |
| 81 | +- **Exploit availability** — Is there public exploit code? |
| 82 | +- **Active exploitation** — Is it being exploited in the wild? |
| 83 | +- **Your exposure** — Is the vulnerable function actually used in your code? |
| 84 | + |
| 85 | +Tools like Snyk add "Exploit Maturity" ratings: |
| 86 | +- **Mature**: Weaponized exploits available |
| 87 | +- **Proof of Concept**: PoC code exists |
| 88 | +- **No Known Exploit**: Theoretical vulnerability |
| 89 | + |
| 90 | +## Direct vs. Transitive Dependencies |
| 91 | + |
| 92 | +Understanding your dependency tree is crucial: |
| 93 | + |
| 94 | +``` |
| 95 | +Your App |
| 96 | +| |
| 97 | +|-- express (direct dependency - you installed this) |
| 98 | +| |-- body-parser (transitive - express needs this) |
| 99 | +| | +-- raw-body |
| 100 | +| | +-- iconv-lite (vulnerable!) |
| 101 | +| +-- cookie |
| 102 | +| |
| 103 | ++-- lodash (direct dependency) |
| 104 | +``` |
| 105 | + |
| 106 | +**Direct dependencies**: Packages you explicitly install (`npm install express`) |
| 107 | + |
| 108 | +**Transitive dependencies**: Packages your dependencies depend on (often 10-100x more than direct) |
| 109 | + |
| 110 | +### Why This Matters |
| 111 | + |
| 112 | +A vulnerability in `iconv-lite` affects your app even though you never installed it directly. Fixing it might require: |
| 113 | + |
| 114 | +1. Updating `express` (if they've updated their dependency) |
| 115 | +2. Waiting for `body-parser` to update (if express hasn't) |
| 116 | +3. Using dependency overrides (forcing a specific version) |
| 117 | + |
| 118 | +```json |
| 119 | +// package.json - forcing a transitive dependency version |
| 120 | +{ |
| 121 | + "overrides": { |
| 122 | + "iconv-lite": "0.6.3" |
| 123 | + } |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +## Lock Files: Your Source of Truth |
| 128 | + |
| 129 | +Lock files pin exact versions of all dependencies (direct + transitive): |
| 130 | + |
| 131 | +| Ecosystem | Lock File | Purpose | |
| 132 | +|-----------|-----------|----------| |
| 133 | +| npm | `package-lock.json` | Exact versions + integrity hashes | |
| 134 | +| Yarn | `yarn.lock` | Exact versions | |
| 135 | +| pnpm | `pnpm-lock.yaml` | Exact versions | |
| 136 | +| Python | `Pipfile.lock`, `poetry.lock` | Exact versions + hashes | |
| 137 | +| Ruby | `Gemfile.lock` | Exact versions | |
| 138 | +| Go | `go.sum` | Checksums (versions in go.mod) | |
| 139 | +| Java | `pom.xml` (with versions) | Declared versions | |
| 140 | + |
| 141 | +**Always commit lock files.** They ensure: |
| 142 | +- Reproducible builds |
| 143 | +- Accurate vulnerability scanning |
| 144 | +- Protection against dependency confusion attacks |
| 145 | + |
| 146 | +## Remediation Strategies |
| 147 | + |
| 148 | +When a vulnerability is found, you have several options: |
| 149 | + |
| 150 | +### 1. Update the Package |
| 151 | + |
| 152 | +The ideal solution—update to a patched version: |
| 153 | + |
| 154 | +```bash |
| 155 | +# npm |
| 156 | +npm update lodash |
| 157 | +npm audit fix |
| 158 | + |
| 159 | +# pip |
| 160 | +pip install --upgrade requests |
| 161 | + |
| 162 | +# bundler |
| 163 | +bundle update nokogiri |
| 164 | +``` |
| 165 | + |
| 166 | +### 2. Override Transitive Dependencies |
| 167 | + |
| 168 | +When the direct dependency hasn't updated yet: |
| 169 | + |
| 170 | +```json |
| 171 | +// npm (package.json) |
| 172 | +{ |
| 173 | + "overrides": { |
| 174 | + "vulnerable-package": "^2.0.0" |
| 175 | + } |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +```yaml |
| 180 | +# Yarn (package.json) |
| 181 | +{ |
| 182 | + "resolutions": { |
| 183 | + "vulnerable-package": "^2.0.0" |
| 184 | + } |
| 185 | +} |
| 186 | +``` |
| 187 | + |
| 188 | +### 3. Ignore with Justification |
| 189 | + |
| 190 | +Sometimes a vulnerability doesn't affect your usage: |
| 191 | + |
| 192 | +```yaml |
| 193 | +# .snyk file |
| 194 | +ignore: |
| 195 | + SNYK-JS-LODASH-1234: |
| 196 | + - '*': |
| 197 | + reason: 'Prototype pollution not exploitable - we never use user input with lodash.merge' |
| 198 | + expires: 2024-12-31 |
| 199 | +``` |
| 200 | +
|
| 201 | +**Document why** you're ignoring—auditors will ask. |
| 202 | +
|
| 203 | +### 4. Replace the Package |
| 204 | +
|
| 205 | +If a package is unmaintained or repeatedly vulnerable: |
| 206 | +
|
| 207 | +```bash |
| 208 | +# Find alternatives |
| 209 | +npx npm-check-updates --doctor |
| 210 | + |
| 211 | +# Or check https://snyk.io/advisor for package health scores |
| 212 | +``` |
| 213 | + |
| 214 | +## Scanning in CI/CD |
| 215 | + |
| 216 | +Dependency scanning belongs in your CI/CD pipeline: |
| 217 | + |
| 218 | +```yaml |
| 219 | +# GitHub Actions example |
| 220 | +name: Security Scan |
| 221 | + |
| 222 | +on: |
| 223 | + push: |
| 224 | + branches: [main] |
| 225 | + pull_request: |
| 226 | + schedule: |
| 227 | + - cron: '0 6 * * *' # Daily at 6 AM |
| 228 | + |
| 229 | +jobs: |
| 230 | + dependency-scan: |
| 231 | + runs-on: ubuntu-latest |
| 232 | + steps: |
| 233 | + - uses: actions/checkout@v4 |
| 234 | + |
| 235 | + - name: Run Snyk |
| 236 | + uses: snyk/actions/node@master |
| 237 | + env: |
| 238 | + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} |
| 239 | + with: |
| 240 | + args: --severity-threshold=high |
| 241 | +``` |
| 242 | +
|
| 243 | +### When to Block Builds |
| 244 | +
|
| 245 | +| Severity | PR Checks | Main Branch | Production | |
| 246 | +|----------|-----------|-------------|------------| |
| 247 | +| Critical | Block | Block | Block | |
| 248 | +| High | Warn | Block | Block | |
| 249 | +| Medium | Warn | Warn | Block | |
| 250 | +| Low | Info | Info | Warn | |
| 251 | +
|
| 252 | +Be pragmatic—blocking every medium vulnerability will frustrate developers and lead to ignored warnings. |
| 253 | +
|
| 254 | +## Key Takeaways |
| 255 | +
|
| 256 | +1. **Dependency scanning compares versions against vulnerability databases**—it doesn't analyze code |
| 257 | +2. **Transitive dependencies are your biggest risk**—they're hidden and numerous |
| 258 | +3. **CVSS scores need context**—exploitability and your exposure matter |
| 259 | +4. **Always commit lock files**—they're essential for accurate scanning |
| 260 | +5. **Scan continuously**—new vulnerabilities are discovered daily |
0 commit comments