Risk OS Red Try Stoa

AI002 · STOA-LLM02-OUTPUT-EXEC

Model output observed reaching a dangerous execution or injection sink.

rule that can fail a build, because a static flow from model output into an execution sink can essentially be proven.

Detection

A taint chain from a model-output source (response.choices[0].message.content, .output_text, llm.invoke(...), generateText(...), streaming deltas, json.loads(<model var>)) to a sink, classified by variant:

variantsinksseveritygate
execeval, exec, os.system, subprocess.*, new Function, child_process.*, vm.runInContextcriticalyes (high conf.)
sqlcursor.execute(f"…"), .raw(), .query() (supersedes SEC003)criticalno
deserializepickle.loads, yaml.load, marshal.loadscriticalno
markupinnerHTML =, dangerouslySetInnerHTML, document.write, Markup, mark_safehighno
requesttainted URL into requests.*/fetch (SSRF-shaped)highno

No sanitizer breaks the exec chain; only dispatch through a static allowlist (using model output solely as a dict/map key) does.

Vulnerable → remediated

# VULNERABLE — model output executed as a shell command
reply = response.choices[0].message.content
subprocess.run(reply.strip(), shell=True)

# REMEDIATED — model selects from a static allowlist; code never runs free text
ACTIONS = {"restart_worker": restart_worker, "clear_cache": clear_cache}
choice = response.choices[0].message.content.strip()
if choice in ACTIONS:
    ACTIONS[choice]()

Finding message

The value from model output reaches a {class}-class sink with no interposed allowlist observed on the flow. Model output is attacker-influenceable whenever any untrusted content reaches the model (OWASP LLM02). (exec/high: this finding is gate-eligible.)

Suppress: # stoa: ignore[AI002] reason