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,50 @@
# API Reference: Testing OAuth2 Implementation Flaws
## OAuth 2.0 Grant Types
| Grant Type | Use Case | Risk Level |
|------------|----------|------------|
| Authorization Code | Server-side apps | Low (with PKCE) |
| Authorization Code + PKCE | Mobile/SPA apps | Low |
| Implicit | Legacy SPAs | High (deprecated) |
| Client Credentials | Machine-to-machine | Medium |
| Resource Owner Password | Legacy migration | High |
## OAuth Attack Surface
| Attack | Severity | Vector |
|--------|----------|--------|
| Redirect URI bypass | Critical | Subdomain, path traversal, encoding |
| Missing state parameter | High | CSRF-based account linking |
| PKCE bypass | High | Authorization code interception |
| Scope escalation | High | Request unauthorized permissions |
| Code reuse | High | Replay authorization code |
| Token in URL fragment | Medium | Referer header leakage |
| Implicit flow | Medium | Token exposure in browser history |
## Redirect URI Bypass Techniques
| Technique | Example |
|-----------|---------|
| Subdomain append | `redirect.com.evil.com` |
| Path traversal | `redirect.com/../evil.com` |
| At-sign confusion | `redirect.com@evil.com` |
| Fragment bypass | `redirect.com%23@evil.com` |
| Query parameter | `redirect.com?next=evil.com` |
| HTTP downgrade | `http://` instead of `https://` |
## Python Libraries
| Library | Version | Purpose |
|---------|---------|---------|
| `requests` | >=2.28 | HTTP OAuth flow testing |
| `secrets` | stdlib | State/nonce generation |
| `urllib.parse` | stdlib | URL parameter encoding |
| `hashlib` | stdlib | PKCE code challenge |
## References
- OAuth 2.0 Security Best Practices: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics
- PortSwigger OAuth: https://portswigger.net/web-security/oauth
- RFC 6749: https://www.rfc-editor.org/rfc/rfc6749
- RFC 7636 (PKCE): https://www.rfc-editor.org/rfc/rfc7636
@@ -0,0 +1,200 @@
#!/usr/bin/env python3
"""Agent for testing OAuth 2.0 implementation flaws.
Tests OAuth authorization code flow, redirect URI validation,
state/PKCE enforcement, token leakage, scope escalation, and
OIDC ID token validation weaknesses.
"""
import json
import sys
import re
import secrets
import hashlib
import base64
from pathlib import Path
from datetime import datetime
from urllib.parse import urlparse, parse_qs, urlencode
try:
import requests
except ImportError:
requests = None
class OAuth2TestAgent:
"""Tests OAuth 2.0 / OIDC implementations for security flaws."""
def __init__(self, auth_url, token_url, client_id, redirect_uri,
output_dir="./oauth2_test"):
self.auth_url = auth_url
self.token_url = token_url
self.client_id = client_id
self.redirect_uri = redirect_uri
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
self.findings = []
def _get(self, url, **kwargs):
if not requests:
return None
kwargs.setdefault("timeout", 10)
kwargs.setdefault("allow_redirects", False)
try:
return requests.get(url, **kwargs)
except requests.RequestException:
return None
def _post(self, url, **kwargs):
if not requests:
return None
kwargs.setdefault("timeout", 10)
try:
return requests.post(url, **kwargs)
except requests.RequestException:
return None
def test_redirect_uri_validation(self):
"""Test redirect_uri for open redirect and bypass techniques."""
bypasses = [
self.redirect_uri + ".evil.com",
self.redirect_uri + "@evil.com",
self.redirect_uri + "/../evil.com",
"https://evil.com",
self.redirect_uri.replace("https://", "http://"),
self.redirect_uri + "%23@evil.com",
self.redirect_uri + "?next=https://evil.com",
]
results = []
for uri in bypasses:
params = {
"response_type": "code", "client_id": self.client_id,
"redirect_uri": uri, "scope": "openid",
"state": secrets.token_urlsafe(16),
}
resp = self._get(f"{self.auth_url}?{urlencode(params)}")
if resp and resp.status_code in (301, 302, 303, 307):
location = resp.headers.get("Location", "")
if "code=" in location or uri in location:
results.append({"redirect_uri": uri, "accepted": True, "location": location[:200]})
self.findings.append({"severity": "critical", "type": "Redirect URI Bypass",
"detail": f"Server accepted redirect_uri: {uri}"})
return results
def test_state_parameter(self):
"""Test if state parameter is enforced (CSRF protection)."""
params = {
"response_type": "code", "client_id": self.client_id,
"redirect_uri": self.redirect_uri, "scope": "openid",
}
resp = self._get(f"{self.auth_url}?{urlencode(params)}")
if resp and resp.status_code in (301, 302, 303, 307):
location = resp.headers.get("Location", "")
if "state=" not in location:
self.findings.append({"severity": "high", "type": "Missing State Parameter",
"detail": "OAuth flow proceeds without state (CSRF risk)"})
return {"state_enforced": False}
return {"state_enforced": True}
def test_pkce_enforcement(self):
"""Test if PKCE is required for public clients."""
params = {
"response_type": "code", "client_id": self.client_id,
"redirect_uri": self.redirect_uri, "scope": "openid",
"state": secrets.token_urlsafe(16),
}
resp = self._get(f"{self.auth_url}?{urlencode(params)}")
if resp and resp.status_code in (301, 302, 303, 307):
self.findings.append({"severity": "high", "type": "PKCE Not Required",
"detail": "Authorization proceeds without code_challenge"})
return {"pkce_required": False}
return {"pkce_required": True}
def test_scope_escalation(self, extra_scopes=None):
"""Test requesting more scopes than authorized."""
scopes = extra_scopes or ["admin", "write", "delete", "users:admin", "openid profile email"]
results = []
for scope in scopes:
params = {
"response_type": "code", "client_id": self.client_id,
"redirect_uri": self.redirect_uri, "scope": scope,
"state": secrets.token_urlsafe(16),
}
resp = self._get(f"{self.auth_url}?{urlencode(params)}")
if resp and resp.status_code in (301, 302, 303, 307):
results.append({"scope": scope, "accepted": True})
self.findings.append({"severity": "high", "type": "Scope Escalation",
"detail": f"Server granted scope: {scope}"})
return results
def test_code_reuse(self, auth_code):
"""Test if authorization code can be reused multiple times."""
data = {
"grant_type": "authorization_code", "code": auth_code,
"client_id": self.client_id, "redirect_uri": self.redirect_uri,
}
resp1 = self._post(self.token_url, data=data)
resp2 = self._post(self.token_url, data=data)
if resp2 and resp2.status_code == 200:
self.findings.append({"severity": "high", "type": "Code Reuse",
"detail": "Authorization code accepted multiple times"})
return {"reusable": True}
return {"reusable": False}
def test_token_in_url(self):
"""Test if implicit flow returns tokens in URL fragment."""
params = {
"response_type": "token", "client_id": self.client_id,
"redirect_uri": self.redirect_uri, "scope": "openid",
"state": secrets.token_urlsafe(16),
}
resp = self._get(f"{self.auth_url}?{urlencode(params)}")
if resp and resp.status_code in (301, 302, 303, 307):
location = resp.headers.get("Location", "")
if "access_token=" in location:
self.findings.append({"severity": "medium", "type": "Implicit Flow Token Exposure",
"detail": "Access token returned in URL fragment"})
return {"token_in_url": True}
return {"token_in_url": False}
def generate_report(self, auth_code=None):
redirect_results = self.test_redirect_uri_validation()
state = self.test_state_parameter()
pkce = self.test_pkce_enforcement()
scope = self.test_scope_escalation()
token_url = self.test_token_in_url()
code_reuse = self.test_code_reuse(auth_code) if auth_code else None
report = {
"report_date": datetime.utcnow().isoformat(),
"auth_url": self.auth_url,
"redirect_uri_bypasses": redirect_results,
"state_parameter": state,
"pkce_enforcement": pkce,
"scope_escalation": scope,
"implicit_flow": token_url,
"code_reuse": code_reuse,
"findings": self.findings,
"total_findings": len(self.findings),
}
out = self.output_dir / "oauth2_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) < 5:
print("Usage: agent.py <auth_url> <token_url> <client_id> <redirect_uri> [--code <auth_code>]")
sys.exit(1)
auth_url, token_url, client_id, redirect_uri = sys.argv[1:5]
code = None
if "--code" in sys.argv:
code = sys.argv[sys.argv.index("--code") + 1]
agent = OAuth2TestAgent(auth_url, token_url, client_id, redirect_uri)
agent.generate_report(code)
if __name__ == "__main__":
main()