Lougarou opened a new pull request, #67075:
URL: https://github.com/apache/airflow/pull/67075
`ImapHook._create_file` wrote downloaded attachments with a plain
`open(file_path, "wb")`, which follows a symlink at the destination. The
existing `_is_symlink` guard in `_create_files` only inspects the bare
attachment `name` relative to the current working directory — not the real
joined output path (`file_path`) that is actually written to.
This hardens `_create_file`:
- it re-checks `os.path.islink` on the real joined target and refuses to
write
through a symlink there, matching the existing `_is_symlink` rejection
style;
- it opens via `os.open` with `O_NOFOLLOW` (feature-gated with
`getattr(os, "O_NOFOLLOW", 0)`, so it is a no-op on Windows, which lacks
the
flag) to also close the check-to-open TOCTOU window.
The open flags are `O_WRONLY | O_CREAT | O_TRUNC` — deliberately **without**
`O_EXCL` — so the hook's existing overwrite-on-redownload behaviour is
preserved; the file mode is `0o600`. Legitimate downloads (including
redownload/overwrite) behave exactly as before; only writes that would pass
through a symlink are now refused.
`test_imap.py` is updated: the `download_mail_attachments` tests now patch
`os.open` / `os.fdopen` instead of the builtin `open`, the symlink test's
`islink` call-count expectation is relaxed (it is now legitimately consulted
in
two places), and two tests are added — one pinning that a symlink at the real
joined target blocks the write, one pinning the `O_NOFOLLOW` / no-`O_EXCL`
flags.
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes (please specify the tool below)
Generated-by: Anthropic Claude (Claude Code) following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
---
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
for more information. Note: commit author/co-author name and email in commits
become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]