Files
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
2026-03-19 13:26:49 +01:00

130 lines
4.5 KiB
Python

#!/usr/bin/env python3
"""Agent for testing Broken Function Level Authorization (BFLA) in APIs."""
import argparse
import json
from datetime import datetime, timezone
try:
import requests
HAS_REQUESTS = True
except ImportError:
HAS_REQUESTS = False
ADMIN_ENDPOINTS = [
"/admin", "/admin/users", "/admin/settings", "/admin/config",
"/api/admin/users", "/api/v1/admin", "/api/internal",
"/manage", "/management", "/dashboard/admin",
"/api/users/all", "/api/config", "/api/debug",
]
HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH"]
def test_endpoint_access(base_url, endpoint, token, method="GET"):
"""Test if an endpoint is accessible with given credentials."""
if not HAS_REQUESTS:
return None
url = f"{base_url.rstrip('/')}{endpoint}"
headers = {"Authorization": f"Bearer {token}"} if token else {}
try:
resp = requests.request(method, url, headers=headers, timeout=10, verify=False)
return {
"endpoint": endpoint,
"method": method,
"status_code": resp.status_code,
"response_size": len(resp.content),
"accessible": resp.status_code < 400,
}
except requests.RequestException:
return None
def test_method_switching(base_url, endpoint, token):
"""Test if changing HTTP method bypasses authorization."""
results = []
for method in HTTP_METHODS:
result = test_endpoint_access(base_url, endpoint, token, method)
if result and result["accessible"]:
results.append(result)
return results
def test_privilege_escalation(base_url, low_priv_token, endpoints=None):
"""Test if low-privilege user can access admin endpoints."""
findings = []
test_endpoints = endpoints or ADMIN_ENDPOINTS
for ep in test_endpoints:
result = test_endpoint_access(base_url, ep, low_priv_token)
if result and result["accessible"]:
findings.append({
"vulnerability": "BFLA",
"endpoint": ep,
"status_code": result["status_code"],
"response_size": result["response_size"],
"severity": "HIGH",
})
return findings
def test_idor_via_function(base_url, token, user_id, target_user_id):
"""Test function-level auth by accessing another user's admin functions."""
findings = []
endpoints = [
f"/api/users/{target_user_id}",
f"/api/users/{target_user_id}/settings",
f"/api/users/{target_user_id}/role",
]
for ep in endpoints:
for method in ["GET", "PUT", "DELETE"]:
result = test_endpoint_access(base_url, ep, token, method)
if result and result["accessible"]:
findings.append({
"vulnerability": "BFLA+IDOR",
"endpoint": ep,
"method": method,
"own_user_id": user_id,
"target_user_id": target_user_id,
})
return findings
def main():
parser = argparse.ArgumentParser(
description="Test Broken Function Level Authorization (authorized testing only)"
)
parser.add_argument("--url", required=True, help="Base API URL")
parser.add_argument("--token", help="Low-privilege user JWT token")
parser.add_argument("--endpoints", nargs="*", help="Custom admin endpoints to test")
parser.add_argument("--user-id", help="Current user ID")
parser.add_argument("--target-id", help="Target user ID for IDOR test")
parser.add_argument("--output", "-o", help="Output JSON report")
args = parser.parse_args()
print("[*] BFLA Testing Agent")
print("[!] For authorized security testing only")
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "target": args.url, "findings": []}
escalation = test_privilege_escalation(args.url, args.token, args.endpoints)
report["findings"].extend(escalation)
print(f"[*] Privilege escalation findings: {len(escalation)}")
if args.user_id and args.target_id:
idor = test_idor_via_function(args.url, args.token, args.user_id, args.target_id)
report["findings"].extend(idor)
print(f"[*] IDOR findings: {len(idor)}")
report["risk_level"] = "CRITICAL" if report["findings"] else "LOW"
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
print(f"[*] Report saved to {args.output}")
else:
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()