Update dependency vcrpy to v8 [SECURITY]#204
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
^6.0.0→^8.0.0VCR.py: Arbitrary code execution via unsafe YAML deserialization of cassette files
GHSA-rpj2-4hq8-938g
More information
Details
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 normalVCR().use_cassette()path, before any HTTP interaction is replayed.This is not limited to environments lacking the libYAML C extension.
CLoaderuses the C parser but PyYAML's full Python constructor, so Pythonobject tags execute under
CLoaderexactly as under the pure-PythonLoader. Confirmed against vcrpy 8.1.1 + PyYAML 6.0.3 withCLoaderactive.Affected component
vcr/serializers/yamlserializer.py—deserialize()→yaml.load(cassette_string, Loader=Loader)whereLoaderisCLoader/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.yamlfile.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
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, with that process's full privileges. Realistic delivery paths:
Because cassettes are typically loaded by test suites in CI/CD and on developer machines, the exposed secrets are exactly the high-value ones in those environments: CI deployment credentials, cloud IAM roles, registry/publishing tokens, and source access.
Patch
Use the safe loader in
vcr/serializers/yamlserializer.py:Apply the same
SafeLoaderchange invcr/migration.py.This is backwards compatible: vcrpy cassettes only contain standard YAML (scalars/lists/maps plus
!!binary, all supported bySafeLoader/CSafeLoader), so existing cassettes load unchanged. vcrpy'sserialize.deserialize()already catchesyaml.constructor.ConstructorError, so a Python-tagged cassette now surfaces as the existing "old cassette format"ValueErrorinstead of executing.Recommended hardening: add a regression test that loads a cassette containing
!!python/object/apply:os.systemand asserts aConstructorError/ValueErrorand that no side effect occurs.Severity
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
kevin1024/vcrpy (vcrpy)
v8.2.1Compare Source
What's Changed
!!python/object/apply:os.system) would execute code on load, including via the normalvcr.use_cassette()path. Existing cassettes (including file-upload/streaming bodies) continue to load. Advisory: GHSA-rpj2-4hq8-938g — thanks @RamiAltai and @EQSTLab for the reports.record_modeand raise a clear error on an invalid value (#208)Full Changelog: kevin1024/vcrpy@v8.2.0...v8.2.1
v8.2.0Compare Source
What's Changed
AsyncStreamReaderMixinremoved andClientResponsenow requiresstream_writer(#995) - thanks @dsfaccinidrop_unused_requestshonoursbefore_record_requestfiltering (#962) - thanks @jamesbrazaVCRHTTPResponse(#976) - thanks @dAnjouconvert_body_to_unicodeto use an explicit type check (#982) - thanks @Polandia94Full Changelog: kevin1024/vcrpy@v8.1.1...v8.2.0
v8.1.1Compare Source
What's Changed
v8.1.0Compare Source
New Features
brotli,brotlipyorbrotlicffi) (#620) - thanks @immerrrBug Fixes
dataandjsonarguments when one is None (#624) - thanks @leorochaelOther Changes
Full Changelog: kevin1024/vcrpy@v8.0.0...v8.1.0
v8.0.0Compare Source
Breaking Changes
New Features
drop_unused_requestsoption to remove unused interactions from cassettes (#763) - thanks @danielnsilvaBug Fixes
httpx.ResponseNotReadexceptions (#832, #834)KeyError: 'follow_redirects'(#945)iscoroutinefunctiondeprecation warning on Python 3.14 - thanks @kloczekOther Changes
Full Changelog: kevin1024/vcrpy@v7.0.0...v8.0.0
v7.0.0Compare Source
What's Changed
New Contributors
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.