Skip to content

fix: replace string-prefix check in safe_extractall with commonpath - #324

Merged
Gi-ron merged 1 commit into
ednx-release/teak.masterfrom
sgb/backport-extract-archive-commonpath-teak
Jul 28, 2026
Merged

fix: replace string-prefix check in safe_extractall with commonpath#324
Gi-ron merged 1 commit into
ednx-release/teak.masterfrom
sgb/backport-extract-archive-commonpath-teak

Conversation

@Gi-ron

@Gi-ron Gi-ron commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Context

The official fix landed on Ulmo, Verawood and master but did not include Teak. Since extract_archive.py is unchanged in our Teak branch relative to upstream, this cherry-pick applies cleanly with no conflicts.

_is_bad_path validated extraction targets with resolved(joinpath(base, path)).startswith(base). safe_extractall appends a trailing separator to output_path, but _checkmembers immediately calls resolved(base), which normalizes it away. The check then matched /data/<base64> as a string prefix of /data/<base64>evil/..., letting a crafted .tar.gz entry such as ../<base64>evil/file write outside the intended extraction directory.

Reached via the Studio course/library import flow (import_olx), which requires the COURSES_IMPORT_COURSE permission — so the attacker must be a course author or staff. Only .tar.gz is practically exploitable, since ZipFile.extractall strips .. segments independently. Realistic impact is limited filesystem corruption and cross-tenant pollution of course import staging directories.

The fix uses commonpath rather than re-appending the separator, making the directory-boundary intent explicit and removing the failure mode entirely. A ValueError guard treats incomparable paths (mixed absolute/relative, different drives) as bad.

Cherry-picked with -x; applied cleanly with no conflicts

`startswith` is the wrong primitive for "is target inside directory base":
once a trailing separator drops anywhere along the way, sibling directories
whose names extend base match. We could spot-fix by re-appending the
separator before the check, but `commonpath` makes the directory-boundary
intent explicit and removes the failure mode entirely.

Fixes GHSA-6cmm-8875-5pcw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 97de058)
@Gi-ron
Gi-ron merged commit c6999bf into ednx-release/teak.master Jul 28, 2026
26 of 47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants