~/teardowns/TD-039.md
←Back to teardowns
# TD-039HighSecurity

The Config File That Executed Itself

yaml.load() turns a settings file into a code-execution vector

Published Oct 29, 2026

Executive Summary

A vibe-coded app loads admin-editable YAML with yaml.load() — the unsafe loader. YAML's !!python/object/apply: tags let a document construct arbitrary Python objects, so a settings file becomes a code-execution payload the moment it is parsed. The file looks like config, but the loader treats it like code.

The Prompt

“Load the site's feature flags from a YAML file that admins can edit in the admin panel.”

The Flaw

yaml.load() (without a SafeLoader) honors YAML tags like !!python/object/apply: that construct arbitrary Python objects. A YAML document is therefore an execution payload, not just data. If the 'admin-editable' file is ever reachable by a less-trusted user — or the admin account is compromised — parsing it runs attacker code.

Risk & Impact

[Security] The feature-flags file is a code-execution vector. The damage depends only on who can write the file, and 'admin-only' is rarely a real boundary.

Cost: Remote code execution once an attacker can edit the settings file.

Code Comparison

❌ Vulnerable (AI generated)

config.pypython
1
2
3
4
5
import yaml
def load_flags(raw):
return yaml.load(raw) # unsafe loader constructs arbitrary objects

The Fix

Use yaml.safe_load() — it only constructs plain dicts/lists/scalars and ignores object tags. Never parse untrusted YAML with the full loader.

Prevention

  • [linter] Bandit flags yaml.load() as high-severity (B506) — fail CI on any use of the unsafe loader.
  • [ci] A test that feeds a YAML document containing !!python/object/apply: must raise or be ignored, never executed.
  • [manual] Pin the exact loader in the prompt (rule 10: 'use safe_load') and forbid object tags (rule 6).

Why This Happened

Root cause: the prompt omitted Rule 6 and Rule 10 — the guardrails that would have caught this. See the full guide →

Sources

Is your codebase vulnerable to this?

Run Diagnostic on My Project →