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
158 changes: 158 additions & 0 deletions .claude/skills/vulnerability-fix/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
name: vulnerability-fix
description: Fix Snyk vulnerabilities using yarn resolutions for patch/minor upgrades
version: 1.0.0
invocable: true
source: manual-session
tags: [security, yarn, snyk, dependencies, vulnerabilities]
---

# Snyk Vulnerabilities with Yarn Resolutions

Fix security vulnerabilities in transitive dependencies using yarn's resolutions field, upgrading only patch and minor versions to avoid breaking changes.

## When to Use

- Snyk reports vulnerabilities in indirect/transitive dependencies
- Vulnerable packages can be fixed with patch or minor version upgrades
- You want to avoid major version upgrades that may introduce breaking changes
- Direct dependency upgrades aren't possible or practical

## Workflow

### 1. Identify Vulnerabilities

```bash
snyk test
```

Analyze the output to identify:

- Vulnerable package names and versions
- Fixed versions available
- Whether fixes require major, minor, or patch upgrades

### 2. Investigate Dependency Tree

For each vulnerable package, check how it's being used:

```bash
yarn why <package-name>
```

This shows:

- Which dependencies require this package
- What version ranges they request
- Multiple versions if present

### 3. Determine Upgrade Strategy

**Only upgrade patch and minor versions:**

- ✅ Patch: `5.2.0` → `5.2.2` (bug fixes, no breaking changes)
- ✅ Minor: `4.17.21` → `4.18.0` (new features, backward compatible)
- ❌ Major: `4.5.3` → `5.3.4` (breaking changes, requires testing)

Sometimes if we can't find a suitable patch/minor version, but a major version is available, we should check if a minor/patch version is available of it's "parent" package that uses the vulnerable package using `yarn why <package-name>`.
In that case, we can upgrade the "parent" package to a minor/patch version that uses a non-vulnerable version of the vulnerable package.

### 4. Add Yarn Resolutions

Edit `package.json` and add to the `resolutions` field:

```json
{
"resolutions": {
"package@^1.2.0": "1.2.5",
"other-package@^4.17.21": "4.17.23"
}
}
```

**Resolution syntax:**

- Use the version range pattern from `yarn why` output
- Specify the exact version to resolve to
- For example: `"diff@^5.1.0": "5.2.2"`

### 5. Apply Resolutions

```bash
yarn install
```

Yarn will output which packages were upgraded/downgraded:

```
➤ YN0085: │ + diff@npm:5.2.2, lodash@npm:4.17.23
➤ YN0085: │ - diff@npm:5.2.0, lodash@npm:4.17.21
```

### 6. Verify Fixes

Run snyk test again to confirm vulnerabilities are resolved:

```bash
snyk test
```

Check that:

- Vulnerability count decreased
- Only major-version issues remain (if any)

### 7. Verify Applied Versions

```bash
yarn why <package-name>
```

Confirm the package is now using the resolved version.

## Example

```bash
# 1. Find vulnerabilities
$ snyk test
# Output: diff@5.2.0 has ReDoS vulnerability, fixed in 5.2.2

# 2. Check dependency tree
$ yarn why diff
# Output: @modelcontextprotocol/server-filesystem uses diff@^5.1.0

# 3. Add resolution to package.json
{
"resolutions": {
"diff@^5.1.0": "5.2.2"
}
}

# 4. Apply changes
$ yarn install
# Output: + diff@npm:5.2.2, - diff@npm:5.2.0

# 5. Verify
$ snyk test
# Vulnerability count reduced
```

## Important Notes

- **Persistence**: Resolutions in `package.json` persist across `yarn install` runs
- **Lock file**: The `yarn.lock` file will be updated with resolved versions
- **Priority**: Resolutions override version ranges specified by dependencies
- **Testing**: Always test your application after applying resolutions
- **Documentation**: Add a comment in package.json explaining why each resolution exists

## Limitations

- Cannot fix vulnerabilities requiring major version upgrades without testing
- Deep transitive dependencies may require multiple resolution entries
- Some packages may have hard requirements on specific versions (peer dependencies)

## Related Documentation

- [Selective dependency resolutions | Yarn](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/)
- [yarn set resolution | Yarn](https://yarnpkg.com/cli/set/resolution)
- [Manifest (package.json) | Yarn](https://yarnpkg.com/configuration/manifest)
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ sig
package.json.back
package.json.onprem
clean.sh
.vscode/launch.json
.vscode/launch.json

# Yarn Berry cache (Yarn 4.x)
.yarn/install-state.gz
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
19 changes: 14 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,27 @@
},
"dependencies": {
"await-semaphore": "^0.1.3",
"axios": "^0.21.0",
"axios": "^1.12.0",
"debounce": "^1.2.1",
"diff": "^5.0.0",
"diff": "^5.2.2",
"eslint-plugin-no-only-tests": "^3.1.0",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.1",
"semver": "^7.3.2",
"systeminformation": "^5.6.10",
"tmp": "^0.2.1",
"underscore": "^1.13.6",
"systeminformation": "^5.31.0",
"tmp": "^0.2.4",
"underscore": "^1.13.8",
"vscode-extension-telemetry": "^0.1.7"
},
"resolutions": {
"brace-expansion@^1.1.7": "1.1.12",
"minimatch@^3.0.3": "3.1.3",
"minimatch@^3.0.4": "3.1.3",
"minimatch@^3.0.5": "3.1.3",
"minimatch@^3.1.2": "3.1.3",
"follow-redirects@^1.14.0": "1.15.9",
"follow-redirects@^1.14.6": "1.15.9"
},
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
Expand Down
Loading