# Dangerous sinks in source code ## Objective An AI agent that executes an action based on what a model just produced — rather than on strictly controlled input — reproduces exactly the classic untrusted-input-to-dangerous-sink pattern, except the untrusted source here is the model's own output, potentially influenced by external content it just read. `detecteur-sinks-llm-dangereux` scans Rust or Python source code and detects cases where a variable likely capturing an LLM output reaches, further down within a bounded line window, a dangerous execution point — a shell command, dynamic evaluation, file write, or SQL query — without an identifiable validation call occurring in between on the same identifier. ## Design: an honest trade-off Correlation by textual identifier within a 25-line window, not real data-flow analysis or actual function-scope tracking. Targeting two languages, one of which (Python) has no braces, would have required two fully separate scope-parsing implementations for a marginal precision gain — honestly documented as a bounded window rather than presented as more rigorous than it is. String and comment masking specific to each language, tested in isolation. > WARNING: the presence of a validation keyword does not mean that validation is actually effective. The tool checks that a call such as sanitize/validate/etc. exists between the source and the sink, never that this call actually neutralizes the risk in question. ## Two real bugs found and fixed before publication Manual testing — not an assumption — revealed two distinct defects before the tool was published. 1. False negative from a bare variable name used as a source pattern: the first version included raw variable names in addition to call shapes. A reassignment line after validation matched itself as a second source point, with no protection behind it — a phantom flag despite the validation already applied upstream. Fixed by restricting source patterns to call shapes only. 2. False negative from identifier prefix collision: one variable name is a substring of another, longer variable name. The correlation check used a plain substring test, so a validation line on the longer variable wrongly neutralized a real flag on the shorter, completely unrelated variable. > TIP: the second bug is the worst kind of error for a security tool — a real risk masked, not just an annoying false positive. Fixed with a strict word-boundary check, with a dedicated regression test so it can never reappear. ## Known limits No alias resolution: a variable reassigned to another via a plain copy is not tracked. The generic file-open pattern in Python is a very common sink pattern in legitimate use, a possible source of false positives if an LLM output variable also serves as a file name already validated some other way. This tool replaces neither a human security review nor real data-flow analysis — it is a fast triage tool, not a proof of absence of risk.