Skip to content

Harden output destination open against symlink clobbering (CWE-59)#763

Closed
thesmartshadow wants to merge 1 commit into
microsoft:mainfrom
thesmartshadow:fix/no-symlink-output
Closed

Harden output destination open against symlink clobbering (CWE-59)#763
thesmartshadow wants to merge 1 commit into
microsoft:mainfrom
thesmartshadow:fix/no-symlink-output

Conversation

@thesmartshadow

Copy link
Copy Markdown

What changed

This PR hardens output file creation on Unix by preventing symlink-following writes at open time.

  • Adds O_NOFOLLOW when opening the destination path (kernel-enforced, avoids TOCTOU-style races).
  • Preserves common stdout targets (/dev/stdout, /proc/self/fd/1, /dev/fd/1) by opening them without O_CREAT/O_TRUNC.
  • Adds a Unix-only regression test that verifies symlink destinations are rejected and do not truncate the symlink target.

Why

The current implementation opens the destination with create(true) + truncate(true). On Unix, that follows symlinks by default. If the destination path is a symlink, the target can be truncated/overwritten.

The regression test specifically covers the important reliability aspect: the destination open happens early, so rejecting symlinks at open time ensures the target cannot be truncated even when later processing fails.

Testing

  • cargo test --release (includes the new tests/symlink_output.rs test)

@thesmartshadow

Copy link
Copy Markdown
Author

Hi I ran into a symlink-following output open on Unix (CWE-59) where the destination could be truncated at open time. This PR hardens the destination open using O_NOFOLLOW (kernel-enforced) while preserving common stdout targets, and adds a small regression test to prevent symlink destinations from truncating the target.

@demoray

demoray commented Mar 23, 2026

Copy link
Copy Markdown
Collaborator

O_NOFOLLOW was added via #754 and released as version 0.17.0

@thesmartshadow

Copy link
Copy Markdown
Author

O_NOFOLLOW was added via #754 and released as version 0.17.0

Hi @demoray thanks for the pointer to #754.

I had reported this issue to MSRC (VULN-174688) in late February. It's great to see it was already addressed in v0.17.0 I'll close this PR as it's no longer needed.

Appreciate the quick fix.

@demoray demoray closed this Mar 24, 2026
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