Initial commit
This commit is contained in:
405
skills/auditing-dependencies/SKILL.md
Normal file
405
skills/auditing-dependencies/SKILL.md
Normal file
@@ -0,0 +1,405 @@
|
||||
---
|
||||
name: auditing-dependencies
|
||||
description: Auditing and updating npm dependencies to prevent security vulnerabilities in TypeScript projects
|
||||
---
|
||||
|
||||
# Security: Dependency Management
|
||||
|
||||
**Purpose:** Prevent security vulnerabilities through proper npm dependency auditing, updating, and monitoring.
|
||||
|
||||
**When to use:** Before adding new dependencies, during security reviews, when setting up CI/CD pipelines, or when package.json changes.
|
||||
|
||||
## Critical Security Principle
|
||||
|
||||
**Dependencies are attack vectors.** Each package you add introduces potential vulnerabilities:
|
||||
- Direct vulnerabilities in the package code
|
||||
- Transitive dependencies (dependencies of dependencies)
|
||||
- Supply chain attacks (malicious package updates)
|
||||
- Unmaintained packages with known CVEs
|
||||
|
||||
**Default stance:** Minimize dependencies. Every package is a liability.
|
||||
|
||||
## Dependency Audit Workflow
|
||||
|
||||
### 1. Check for Known Vulnerabilities
|
||||
|
||||
**Before installing any package:**
|
||||
|
||||
```bash
|
||||
npm audit
|
||||
```
|
||||
|
||||
This shows:
|
||||
- Severity levels (critical, high, moderate, low)
|
||||
- Vulnerable packages and versions
|
||||
- Recommended fixes
|
||||
- Dependency path showing how vulnerability entered
|
||||
|
||||
**Read the output carefully.** Not all vulnerabilities affect your code:
|
||||
- Check if vulnerable code path is used
|
||||
- Assess actual risk vs theoretical risk
|
||||
- Prioritize fixes by severity and exploitability
|
||||
|
||||
### 2. Update Vulnerable Packages
|
||||
|
||||
**Automatic fixes (use with caution):**
|
||||
|
||||
```bash
|
||||
npm audit fix
|
||||
```
|
||||
|
||||
This updates packages to non-breaking versions that patch vulnerabilities.
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
```bash
|
||||
npm audit fix --force
|
||||
```
|
||||
|
||||
This updates to latest versions, potentially breaking your code. Use only after:
|
||||
- Reading breaking change notes
|
||||
- Having comprehensive test coverage
|
||||
- Being prepared to fix broken code
|
||||
|
||||
**Manual selective updates:**
|
||||
|
||||
```bash
|
||||
npm update package-name
|
||||
```
|
||||
|
||||
Update specific packages after reviewing their changelogs.
|
||||
|
||||
### 3. Prevent Vulnerable Installations
|
||||
|
||||
**Block installations with vulnerabilities:**
|
||||
|
||||
Create `.npmrc` in project root:
|
||||
|
||||
```
|
||||
audit-level=moderate
|
||||
```
|
||||
|
||||
This fails `npm install` if moderate or higher severity vulnerabilities exist.
|
||||
|
||||
**In CI/CD:**
|
||||
|
||||
```yaml
|
||||
- name: Security audit
|
||||
run: |
|
||||
npm audit --audit-level=moderate
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Security vulnerabilities found!"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### 4. Monitor Dependencies Continuously
|
||||
|
||||
**GitHub Dependabot:**
|
||||
|
||||
Enable in repository settings → Security → Dependabot alerts.
|
||||
|
||||
Automatically:
|
||||
- Scans dependencies daily
|
||||
- Creates PRs for security updates
|
||||
- Provides vulnerability details
|
||||
|
||||
**npm-check-updates:**
|
||||
|
||||
```bash
|
||||
npx npm-check-updates
|
||||
```
|
||||
|
||||
Shows available updates for all dependencies.
|
||||
|
||||
```bash
|
||||
npx npm-check-updates -u
|
||||
```
|
||||
|
||||
Updates package.json (still need to run `npm install`).
|
||||
|
||||
## Dependency Selection Best Practices
|
||||
|
||||
### Before Adding Any Dependency
|
||||
|
||||
**Ask these questions:**
|
||||
|
||||
1. **Do I actually need this?**
|
||||
- Can I write the functionality myself in < 100 lines?
|
||||
- Am I using 10% of the package's features?
|
||||
- Is this adding significant bundle size for trivial functionality?
|
||||
|
||||
2. **Is this package trustworthy?**
|
||||
- Check npm weekly downloads (high is better)
|
||||
- Check GitHub stars and recent activity
|
||||
- Check last publish date (recent is better, but stable packages may be older)
|
||||
- Look for security track record
|
||||
|
||||
3. **Is this package maintained?**
|
||||
- When was last commit?
|
||||
- Are issues being responded to?
|
||||
- Are security issues addressed quickly?
|
||||
- Is there a clear maintenance policy?
|
||||
|
||||
4. **What are the transitive dependencies?**
|
||||
```bash
|
||||
npm ls package-name
|
||||
```
|
||||
Each transitive dependency is another attack vector.
|
||||
|
||||
### Red Flags
|
||||
|
||||
**Avoid packages with:**
|
||||
- No TypeScript types (requires `@types/` package or no types at all)
|
||||
- Abandoned for > 2 years with no successor
|
||||
- Known security vulnerabilities with no fix available
|
||||
- Excessive transitive dependencies (> 50 packages)
|
||||
- Requires `postinstall` scripts (potential supply chain attack vector)
|
||||
- Very small packages doing trivial things (left-pad scenario)
|
||||
|
||||
### Safer Alternatives
|
||||
|
||||
**Use built-in Node.js/browser features when possible:**
|
||||
|
||||
```typescript
|
||||
import { randomBytes } from 'crypto';
|
||||
const id = randomBytes(16).toString('hex');
|
||||
```
|
||||
|
||||
Better than installing `uuid` package if you just need random IDs.
|
||||
|
||||
```typescript
|
||||
const url = new URL('/api/users', 'https://api.example.com');
|
||||
url.searchParams.set('limit', '10');
|
||||
```
|
||||
|
||||
Better than installing query string builder packages.
|
||||
|
||||
## Lock Files and Reproducible Builds
|
||||
|
||||
### Always Commit Lock Files
|
||||
|
||||
**package-lock.json** (npm) or **yarn.lock** (Yarn) must be committed:
|
||||
- Ensures exact same dependency versions across environments
|
||||
- Prevents supply chain attacks via dependency version updates
|
||||
- Makes builds reproducible
|
||||
|
||||
**Never:**
|
||||
- Add lock files to `.gitignore`
|
||||
- Delete lock files to "fix" problems
|
||||
- Run `npm install` with `--no-package-lock`
|
||||
|
||||
### Use Specific Version Ranges
|
||||
|
||||
**In package.json, prefer exact versions for critical dependencies:**
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"express": "4.18.2",
|
||||
"zod": "3.22.4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Not:
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"zod": "~3.22.4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Rationale:** Caret (`^`) and tilde (`~`) allow automatic updates that could introduce breaking changes or vulnerabilities.
|
||||
|
||||
**Exception:** Development dependencies can use ranges if you regularly update them.
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### Required Security Checks
|
||||
|
||||
**Every CI pipeline must:**
|
||||
|
||||
1. **Run audit on every build:**
|
||||
```yaml
|
||||
- run: npm audit --audit-level=moderate
|
||||
```
|
||||
|
||||
2. **Check for outdated dependencies weekly:**
|
||||
```yaml
|
||||
schedule:
|
||||
- cron: '0 0 * * 1'
|
||||
jobs:
|
||||
update-check:
|
||||
- run: npx npm-check-updates
|
||||
```
|
||||
|
||||
3. **Prevent merging PRs with vulnerabilities:**
|
||||
```yaml
|
||||
- name: Security gate
|
||||
run: npm audit --production --audit-level=moderate
|
||||
```
|
||||
|
||||
### Example GitHub Actions Workflow
|
||||
|
||||
```yaml
|
||||
name: Security Audit
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * 1'
|
||||
|
||||
jobs:
|
||||
audit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
- run: npm ci
|
||||
- run: npm audit --audit-level=moderate
|
||||
- name: Check for outdated packages
|
||||
run: npx npm-check-updates
|
||||
```
|
||||
|
||||
## Handling Vulnerabilities That Can't Be Fixed
|
||||
|
||||
### Scenario: Dependency has vulnerability, no fix available
|
||||
|
||||
**Options:**
|
||||
|
||||
1. **Find alternative package:**
|
||||
- Research similar packages without the vulnerability
|
||||
- Consider rewriting functionality if simple
|
||||
|
||||
2. **Assess actual risk:**
|
||||
- Is vulnerable code path used in your application?
|
||||
- Is vulnerability exploitable in your context?
|
||||
- Document risk assessment
|
||||
|
||||
3. **Audit exception (last resort):**
|
||||
```bash
|
||||
npm audit --json > audit-baseline.json
|
||||
```
|
||||
|
||||
Document why exception is acceptable:
|
||||
- What is the vulnerability?
|
||||
- Why can't it be fixed?
|
||||
- What mitigations are in place?
|
||||
- When will this be reviewed again?
|
||||
|
||||
**Never ignore vulnerabilities permanently.**
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
### Mistake 1: Installing packages without checking
|
||||
|
||||
```bash
|
||||
npm install some-random-package
|
||||
```
|
||||
|
||||
**Correct approach:**
|
||||
|
||||
1. Check package on npm registry
|
||||
2. Review GitHub repository
|
||||
3. Check bundle size: `bundlephobia.com`
|
||||
4. Run `npm audit` after installation
|
||||
5. Review lock file changes in git diff
|
||||
|
||||
### Mistake 2: Ignoring audit warnings
|
||||
|
||||
"It's just a moderate severity in a dev dependency, doesn't matter."
|
||||
|
||||
**Wrong.** Development dependencies:
|
||||
- Can be compromised and steal secrets
|
||||
- Run with same permissions as your code
|
||||
- Can modify source files during build
|
||||
|
||||
### Mistake 3: Using `--force` without understanding
|
||||
|
||||
```bash
|
||||
npm install --force
|
||||
```
|
||||
|
||||
This bypasses dependency resolution and can install incompatible versions.
|
||||
|
||||
**Only use when:**
|
||||
- You understand exactly what it does
|
||||
- You've read the conflict details
|
||||
- You have tests to verify nothing broke
|
||||
|
||||
## Maintenance Schedule
|
||||
|
||||
**Weekly:**
|
||||
- Review Dependabot PRs
|
||||
- Run `npm audit`
|
||||
|
||||
**Monthly:**
|
||||
- Run `npx npm-check-updates`
|
||||
- Update non-breaking dependencies
|
||||
- Test thoroughly
|
||||
|
||||
**Quarterly:**
|
||||
- Plan major version updates
|
||||
- Review all dependencies for continued need
|
||||
- Remove unused packages
|
||||
|
||||
## TypeScript-Specific Considerations
|
||||
|
||||
### Type Definition Security
|
||||
|
||||
**Check if types match runtime:**
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod';
|
||||
|
||||
const APIResponseSchema = z.object({
|
||||
data: z.array(z.string()),
|
||||
});
|
||||
|
||||
type APIResponse = z.infer<typeof APIResponseSchema>;
|
||||
```
|
||||
|
||||
This ensures types and runtime validation stay synchronized.
|
||||
|
||||
### Type-Only Imports for Tree-Shaking
|
||||
|
||||
```typescript
|
||||
import type { User } from 'huge-library';
|
||||
```
|
||||
|
||||
This imports only types, not runtime code, reducing bundle size.
|
||||
|
||||
## Resources
|
||||
|
||||
**Tools:**
|
||||
- `npm audit` - Built-in vulnerability scanner
|
||||
- `npm-check-updates` - Dependency update checker
|
||||
- Snyk - Commercial vulnerability scanning
|
||||
- GitHub Dependabot - Automated security updates
|
||||
|
||||
**References:**
|
||||
- [npm audit documentation](https://docs.npmjs.com/cli/v10/commands/npm-audit)
|
||||
- [OWASP Dependency Check](https://owasp.org/www-project-dependency-check/)
|
||||
- [Sonatype State of Software Supply Chain](https://www.sonatype.com/state-of-the-software-supply-chain)
|
||||
|
||||
## Summary Checklist
|
||||
|
||||
Before merging any dependency changes:
|
||||
|
||||
- [ ] `npm audit` passes at moderate level or higher
|
||||
- [ ] Reviewed what the package does and alternatives considered
|
||||
- [ ] Checked package maintenance status and security history
|
||||
- [ ] Lock file committed with changes
|
||||
- [ ] CI pipeline includes security audit
|
||||
- [ ] Transitive dependencies reviewed (not excessive)
|
||||
- [ ] Bundle size impact assessed for frontend projects
|
||||
- [ ] Types available and trustworthy
|
||||
|
||||
**Remember:** The best dependency is the one you don't add. The second best is one that's actively maintained with a strong security track record.
|
||||
Reference in New Issue
Block a user