CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-rpj2-4hq8-938g: VCR.py: Arbitrary code execution via unsafe YAML deserialization of cassette files

highCVSS 7.8
Summary vcrpy deserializes YAML cassette files with PyYAML's object-constructing loader (yaml.CLoader / yaml.Loader) instead of the safe loader (yaml.CSafeLoader / yaml.SafeLoader). A cassette containing a !!python/object/apply: (or similar) tag therefore executes arbitrary Python code the moment the cassette is loaded — including through the normal VCR().use_cassette() path, before any HTTP interaction is replayed. This is not limited to environments lacking the libYAML C extension. CLoader uses the C parser but PyYAML's full Python *constructor*, so Python object tags execute under CLoader exactly as under the pure-Python Loader. Confirmed against vcrpy 8.1.1 + PyYAML 6.0.3 with CLoader active. Affected component - vcr/serializers/yamlserializer.py — deserialize() → yaml.load(cassette_string, Loader=Loader) where Loader is CLoader/Loader. Reached on every cassette load. - vcr/migration.py (~line 107) — yaml.load(preprocess_yaml(...), Loader=Loader). A second sink reached when the migration tool is run on a .yaml file. preprocess_yaml() only strips three known legacy tags, so other tags still execute. Present in all releases inspected, 1.0.0 through 8.1.1. Proof of concept import vcr, requests Attacker-supplied cassette. The payload sits in an ignored top-level key so the rest of the cassette stays valid; it fires during load. open("evil.yaml", "w").write("""interactions: - request: body: null headers: {Accept: ['*/*']} method: GET uri: http://example.com/ response: body: {string: ok} headers: {Content-Type: ['text/plain']} status: {code: 200, message: OK} _x: !!python/object/apply:os.system ['touch /tmp/VCRPY_YAML_RCE'] version: 1 """) with vcr.use_cassette("evil.yaml"): # <-- /tmp/VCRPY_YAML_RCE created here requests.get("http://example.com/") Loading the cassette creates /tmp/VCRPY_YAML_RCE, demonstrating arbitrary command execution. Any Python callable can be invoked this way. Impact Arbitrary code execution in the process that loads the cassette, w

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 7.8
Published
2026-06-19
Last updated
2026-07-10
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-rpj2-4hq8-938g

More from GitHub Security Advisories