#!/usr/bin/env python3
"""Agent for implementing API threat protection policies with Google Apigee."""
import json
import argparse
import re
from datetime import datetime
from pathlib import Path
APIGEE_POLICIES = {
"JSONThreatProtection": {
"max_depth": 5, "max_string_length": 500,
"max_entries": 25, "max_array_elements": 100,
},
"XMLThreatProtection": {
"max_depth": 5, "max_attributes": 10,
"max_element_name_length": 128, "max_text_length": 500,
},
"RegularExpressionProtection": {
"patterns": [
r"[\s]*((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update)|(or))",
r"<\s*script\b[^>]*>[^<]+<\s*/\s*script\s*>",
r"(\%27)|(\')|(\-\-)|(\%23)|(#)",
]
},
"SpikeArrest": {
"rate": "30ps", "identifier": "request.header.x-api-key",
},
}
def generate_json_threat_policy(config=None):
"""Generate Apigee JSONThreatProtection policy XML."""
cfg = config or APIGEE_POLICIES["JSONThreatProtection"]
return f"""
JSON Threat Protection
{cfg['max_entries']}
{cfg['max_array_elements']}
{cfg['max_depth']}
{cfg['max_string_length']}
request
"""
def generate_spike_arrest_policy(rate="30ps"):
"""Generate Apigee SpikeArrest policy XML."""
return f"""
Spike Arrest
{rate}
true
"""
def generate_regex_protection_policy():
"""Generate RegularExpressionProtection policy for SQL/XSS."""
return """
SQL Injection and XSS Protection
request
[\s]*((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update))
<\\s*script\\b[^>]*>
$.*
[\s]*((delete)|(exec)|(drop\s*table)|(insert)|(shutdown)|(update))
"""
def analyze_apigee_proxy_bundle(bundle_path):
"""Analyze an Apigee proxy bundle for security policy gaps."""
findings = []
bundle = Path(bundle_path)
policies_dir = bundle / "apiproxy" / "policies"
if not policies_dir.exists():
return [{"issue": "no_policies_directory", "severity": "CRITICAL"}]
policy_files = list(policies_dir.glob("*.xml"))
policy_names = [p.stem for p in policy_files]
required_policies = [
("JSONThreatProtection", "json_threat_protection", "HIGH"),
("SpikeArrest", "spike_arrest", "HIGH"),
("OAuthV2", "oauth_authentication", "CRITICAL"),
("CORS", "cors_policy", "MEDIUM"),
]
for policy_type, issue_name, severity in required_policies:
has_policy = any(policy_type.lower() in p.lower() for p in policy_names)
if not has_policy:
for pf in policy_files:
content = pf.read_text(errors="ignore")
if policy_type in content:
has_policy = True
break
if not has_policy:
findings.append({
"issue": f"missing_{issue_name}",
"policy_type": policy_type,
"severity": severity,
})
return findings
def audit_threat_protection_config(policy_path):
"""Audit a threat protection policy for weak configurations."""
findings = []
content = Path(policy_path).read_text(errors="ignore")
depth_match = re.search(r"(\d+)", content)
if depth_match and int(depth_match.group(1)) > 10:
findings.append({
"issue": "excessive_container_depth",
"value": int(depth_match.group(1)),
"recommended": 5, "severity": "MEDIUM",
})
string_match = re.search(r"(\d+)", content)
if string_match and int(string_match.group(1)) > 10000:
findings.append({
"issue": "excessive_string_length",
"value": int(string_match.group(1)),
"recommended": 500, "severity": "MEDIUM",
})
rate_match = re.search(r"(\d+)(ps|pm)", content)
if rate_match:
rate_val = int(rate_match.group(1))
unit = rate_match.group(2)
if unit == "ps" and rate_val > 100:
findings.append({
"issue": "spike_arrest_too_permissive",
"rate": f"{rate_val}{unit}", "severity": "HIGH",
})
return findings
def main():
parser = argparse.ArgumentParser(description="Apigee API Threat Protection Agent")
parser.add_argument("--action", choices=[
"generate", "audit_bundle", "audit_policy", "full"
], default="generate")
parser.add_argument("--bundle", help="Apigee proxy bundle path")
parser.add_argument("--policy", help="Policy XML file to audit")
parser.add_argument("--output", default="apigee_threat_protection_report.json")
args = parser.parse_args()
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
if args.action == "generate":
report["policies"] = {
"json_threat_protection": generate_json_threat_policy(),
"spike_arrest": generate_spike_arrest_policy(),
"regex_protection": generate_regex_protection_policy(),
}
print("[+] Generated 3 Apigee security policies")
if args.action in ("audit_bundle", "full") and args.bundle:
f = analyze_apigee_proxy_bundle(args.bundle)
report["findings"]["bundle_audit"] = f
print(f"[+] Bundle audit findings: {len(f)}")
if args.action in ("audit_policy", "full") and args.policy:
f = audit_threat_protection_config(args.policy)
report["findings"]["policy_audit"] = f
print(f"[+] Policy audit findings: {len(f)}")
with open(args.output, "w") as fout:
json.dump(report, fout, indent=2, default=str)
print(f"[+] Report saved to {args.output}")
if __name__ == "__main__":
main()