Skip to content

tech-debt: write-path TOCTOU hardening — openat/O_NOFOLLOW (S1) #160

Description

@dean0x

Problem

Both mds fmt and mds build write output files after canonicalizing the path. Between canonicalize and the actual write, an attacker could swap a symlink, causing the formatter/builder to write to an unintended location.

This is a TOCTOU (Time-of-check, time-of-use) vulnerability in both write paths. The window is small but exploitable in high-volume CI or batch scenarios.

Solution

Harden both write paths using openat + O_NOFOLLOW (or Rust equivalent):

  • Implement write-safe path handling in crates/mds-cli/src/fmt.rs (mds fmt)
  • Apply same pattern to crates/mds-cli/src/build.rs (mds build)
  • Use Rust's std::fs::OpenOptions with custom flags, or a crate like openat if needed
  • Add integration tests verifying the symlink-swap attack is prevented
  • Document the defense in code comments

Notes

  • This is security hardening for an edge case, not an immediate critical issue.
  • The pattern already exists in other MDS write code; this unifies the approach codebase-wide.
  • Both fmt and build write paths should be fixed together for consistency.

Acceptance Criteria

  • Both write paths updated to use O_NOFOLLOW equivalent
  • Integration test added for symlink-swap prevention
  • All existing tests pass
  • Clippy and fmt are clean
  • Code comments explain the defense

Reference

Surfaced in: PR #137 (mds fmt formatter) code review, deferred-to-tech-debt section.
Codebase-wide concern: applies to both fmt and build write paths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliCLI commands and optionstech-debtTechnical debt

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions