Skip to content

reject mixed-separator path traversal in imap attachment names - #70665

Merged
potiuk merged 2 commits into
apache:mainfrom
Samin061:imap-attachment-separator-traversal
Aug 1, 2026
Merged

reject mixed-separator path traversal in imap attachment names#70665
potiuk merged 2 commits into
apache:mainfrom
Samin061:imap-attachment-separator-traversal

Conversation

@Samin061

Copy link
Copy Markdown
Contributor

_is_escaping_current_directory in the imap hook rejects a traversing attachment name with f"..{os.sep}" in name, which is tied to the host separator. On Windows os.sep is a backslash but a forward slash is also a valid path separator, so an attachment named ../../evil slips past the check and, once joined onto the output directory in _correct_path, resolves outside it, letting whoever sent the mail write an arbitrary file. This normalises both separators and rejects any .. path component instead.


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Comment thread providers/imap/src/airflow/providers/imap/hooks/imap.py Outdated

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fix. Tying the check to os.sep meant that on Windows, where / is equally valid as a separator, ../../evil walked straight past the guard — and attachment names come from email, so that input is attacker-controlled whenever the mailbox receives external mail.

The revision addresses the earlier review point properly: using os.sep plus os.altsep keeps backslashes as ordinary characters on POSIX while catching both separators on Windows, and the two parametrized tests lock that platform difference in. ("..\\..\\test1.csv", False) on POSIX is exactly the case worth pinning.

I checked the obvious follow-on question — absolute names like /etc/passwd — and they are covered, though somewhat by accident: _correct_path concatenates strings rather than using os.path.join, so an absolute name becomes /out//etc/passwd and stays inside the directory. Worth knowing that this is load-bearing, since switching that concatenation to os.path.join later would reintroduce an escape that this check does not cover.

Splitting on components also catches a bare .. that the old substring test missed, which is a nice bonus even though it isn't exploitable on its own.


Drafted-by: Claude Code (Opus 5); reviewed by @potiuk before posting

@potiuk
potiuk force-pushed the imap-attachment-separator-traversal branch from 4180097 to dab673d Compare August 1, 2026 02:49
@potiuk
potiuk merged commit e7ffeb7 into apache:main Aug 1, 2026
79 checks passed
dabla pushed a commit to dabla/airflow that referenced this pull request Aug 14, 2026
…e#70665)

* reject mixed-separator path traversal in imap attachment names

* Use os.altsep for separator-agnostic imap traversal check

Signed-off-by: bibi samina <sam@bugqore.com>

---------

Signed-off-by: bibi samina <sam@bugqore.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants