Skip to content

Dataset builders download only into a directory you own - #273

Draft
jaredpalmer wants to merge 2 commits into
mainfrom
cursor/private-download-dir-519a
Draft

jaredpalmer wants to merge 2 commits into
mainfrom
cursor/private-download-dir-519a

Conversation

@jaredpalmer

Copy link
Copy Markdown
Owner

scripts/build_devtools_v1.py downloads with curl -o <target>.part into --raw, which defaults to /tmp/devtools-raw. scripts/build_breadth_v1.py uses the same fetch and defaults to /tmp/breadth-raw. The directory is created with exist_ok and its owner and mode are never checked. On a shared POSIX machine another local user can create that directory first and plant <target>.part as a symlink. curl -o follows it and overwrites the symlink's target as the user running the builder. Most of those files are then checked against a pinned sha256, so a swapped file fails the build. The FlakeFlagger GitHub tarball is not pinned at fetch time. Its hash is recorded in the manifest after the build, so a planted copy would be used as it is.

fetch now writes only into a directory the caller owns, with no group or other write bit. A missing directory is created mode 0700. An existing directory the user owns at mode 0755 still works. That is what the old mkdir produced under a normal umask. A symlink is refused rather than followed. The bytes go to an mkstemp file in that directory, and os.replace moves it onto the target. A failed curl removes the temp file and leaves no target. On Windows the ownership check is skipped and the directory is still created.

This keeps Wenjix's commit from #268. I dropped the AGENTS.md sentence. It was inserted into the devtools-v1 parenthetical, which is about CodeReviewer ids and state keys, and it mentioned breadth-v1 from inside that parenthesis. private_dir's docstring and the error text are the contract.

Not in this PR: pinning the FlakeFlagger tarball. GitHub codeload archives are not promised to stay byte-identical. Also not here: the kev-finetune scripts. Those stay standard library. This builder already imports kev.

Test plan

  • tests/test_devtools_v1.py and tests/test_conventions.py: 79 passed. Covers a planted <name>.part symlink left untouched, a mode 0777 directory refused before any download, a missing directory created 0700, and a failed curl leaving the directory empty.
  • CI
Open in Web Open in Cursor 

Wenjix and others added 2 commits October 27, 2026 13:45
fetch wrote each download to a predictable <target>.part in a /tmp
directory it never checked, so another local user could plant a
symlink there and have curl overwrite its target. Downloads now go
only into a directory owned by the caller with no group or other
write bit (created 0700), through an mkstemp file moved into place
with os.replace and removed on failure.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
private_dir's docstring and its error are the contract. The suite paragraph is about labels and ids, and breadth-v1 does not belong inside it.

Co-authored-by: Jared Palmer <hello@jaredpalmer.com>
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.

3 participants