| name | supply-chain-checklist |
| description | Checklist for passive supply chain security assessment. Covers JavaScript library identification, known CVEs, SRI, source maps, and exposed dependency files. |
| allowed-tools | Read, Grep, Glob, WebSearch, Bash(curl:*), Bash(python:*), Bash(python3:*), Bash(grep:*), Bash(head:*), Bash(tail:*), Bash(echo:*), Bash(cat:*), Bash(jq:*), mcp__plugin_playwright_playwright__browser_navigate, mcp__plugin_playwright_playwright__browser_snapshot, mcp__plugin_playwright_playwright__browser_evaluate, mcp__plugin_playwright_playwright__browser_run_code, mcp__plugin_playwright_playwright__browser_close |
1. JavaScript Library Identification
Methods to detect libraries and versions:
From CDN URLs
Parse <script src="..."> tags for version patterns:
jquery-3.6.0.min.js, react@18.2.0, vue@3.3.4
- CDN URLs:
cdnjs.cloudflare.com, cdn.jsdelivr.net, unpkg.com
From Global Variables (Playwright)
const libs = {};
if (window.jQuery) libs['jquery'] = window.jQuery.fn.jquery;
if (window.$?.fn?.jquery) libs['jquery'] = window.$.fn.jquery;
if (window.React) libs['react'] = window.React.version;
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) libs['react'] = 'detected (version from devtools hook)';
if (window.Vue) libs['vue'] = window.Vue.version;
if (window.__VUE__) libs['vue'] = 'detected (v3)';
if (window.angular) libs['angularjs'] = window.angular.version.full;
if (window.ng?.coreTokens) libs['angular'] = 'detected (v2+)';
if (window.bootstrap?.Tooltip?.VERSION) libs['bootstrap'] = window.bootstrap.Tooltip.VERSION;
if (window._?.VERSION) libs['lodash'] = window._.VERSION;
if (window.moment?.version) libs['moment'] = window.moment.version;
if (window.d3?.version) libs['d3'] = window.d3.version;
if (window.THREE?.REVISION) libs['three'] = window.THREE.REVISION;
if (window.axios?.VERSION) libs['axios'] = window.axios.VERSION;
JSON.stringify(libs, null, 2);
From JS Comments/Banners
Check first few lines of JS files for version comments:
const scripts = Array.from(document.querySelectorAll('script[src]')).map(s => s.src);
From meta tags and HTML generators
const generator = document.querySelector('meta[name="generator"]')?.content;
2. Known CVE Lookup
For each detected library+version, search for known vulnerabilities:
- Use WebSearch tool:
"<library> <version> CVE vulnerability"
- Check specific databases:
- Snyk:
https://security.snyk.io/package/npm/<package>
- NVD: search for library name in CVE database
- GitHub Advisories:
https://github.com/advisories?query=<library>
Classification:
- Library with known Critical CVE → Critical
- Library with known High CVE → High
- Library with known Medium CVE → Medium
- Outdated library (no known CVE) → Low
3. Subresource Integrity (SRI)
Check all external scripts and stylesheets for integrity attribute:
const resources = Array.from(document.querySelectorAll('script[src], link[rel="stylesheet"][href]'));
const external = resources.filter(el => {
const url = el.src || el.href;
return url && (url.startsWith('http://') || url.startsWith('https://')) && !url.includes(window.location.hostname);
});
const noSRI = external.filter(el => !el.integrity).map(el => ({
tag: el.tagName.toLowerCase(),
url: el.src || el.href,
hasCrossorigin: el.hasAttribute('crossorigin')
}));
JSON.stringify(noSRI, null, 2);
External scripts without SRI: Medium severity.
External scripts without SRI from HTTP (not HTTPS): High severity.
4. Source Map Exposure
For each JS file found on the page:
Check sourceMappingURL comments
const scripts = Array.from(document.querySelectorAll('script[src]')).map(s => s.src);
Probe for .map files
curl -sI "https://TARGET/path/to/bundle.js.map" -o /dev/null -w "%{http_code}"
curl -sI "https://TARGET/path/to/main.js.map" -o /dev/null -w "%{http_code}"
Source maps exposed: High severity (leaks original source code, comments, variable names).
5. Exposed Dependency Files
Probe for publicly accessible dependency manifests:
for file in /package.json /package-lock.json /yarn.lock /pnpm-lock.yaml /composer.json /composer.lock /Gemfile /Gemfile.lock /requirements.txt /Pipfile /Pipfile.lock /go.mod /go.sum /Cargo.toml /Cargo.lock /pom.xml /build.gradle /mix.exs; do
code=$(curl -sI "https://TARGET${file}" -o /dev/null -w "%{http_code}")
[ "$code" = "200" ] && echo "EXPOSED: $file"
done
If package.json is accessible, parse it for dependencies and versions:
curl -s "https://TARGET/package.json" | python3 -c "
import sys, json
try:
pkg = json.load(sys.stdin)
deps = {**pkg.get('dependencies', {}), **pkg.get('devDependencies', {})}
for name, version in sorted(deps.items()):
print(f'{name}: {version}')
except: pass
"
6. Outdated Framework Detection
Check meta generators and known version patterns:
- WordPress:
<meta name="generator" content="WordPress X.Y.Z">
- Drupal:
<meta name="generator" content="Drupal X">
- Joomla:
<meta name="generator" content="Joomla!">
- Next.js:
__NEXT_DATA__ in page source
- Nuxt.js:
__NUXT__ in page source
For CMS detection, check:
curl -s https://TARGET/wp-includes/version.php 2>/dev/null | head -20
curl -s https://TARGET/readme.html 2>/dev/null | head -20
curl -s https://TARGET/CHANGELOG.md 2>/dev/null | head -5
curl -s https://TARGET/CHANGES.md 2>/dev/null | head -5
Severity Assessment Guide
| Finding | Severity |
|---|
| Library with known Critical CVE | Critical |
| Library with known High CVE | High |
| Source maps exposed (leaking source) | High |
| package.json/lock exposed | Medium |
| Missing SRI on external CDN scripts | Medium |
| Outdated library (no known CVE) | Low |
| Exposed .map files without sensitive data | Medium |
| requirements.txt/Gemfile exposed | Medium |
| CMS with known version (no CVE) | Low |
| Generator meta tag present | Info |
Finding Report Format
Each finding MUST follow this format:
### [SEVERITY] Problem title
- **URL/Evidence:** specific URL, header, code fragment
- **Risk:** technical + business risk description
- **Recommendation:** what to do (with config/code example)
- **Verification:** how to confirm the fix
- **Owner:** Dev / DevOps / Security