Repository navigation
Refuse secret key/token writes through a planted dest symlink - #365
Merged
Merged
Conversation
write_key_file and admin-token generate opened the dest with O_CREAT|O_TRUNC, which follows a symlink. A planted ~/.arbiter/openrouter_api_key, search_api_key, or admin_token link redirected the secret into the target. Shared write_secret_file opens with O_NOFOLLOW and requires a regular file so a dest symlink or FIFO cannot exfiltrate the bytes. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Tyler Reckart <tylerreckart@users.noreply.github.com>
…-nofollow # Conflicts: # CHANGELOG.md
tylerreckart
marked this pull request as ready for review
September 21, 2026 12:58
tylerreckart
enabled auto-merge (squash)
September 21, 2026 12:58
Keep both Unreleased notes after #366 landed on main (CHANGELOG only). Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Tyler Reckart <tylerreckart@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
write_key_file(setup wizard /set_search_api_key) and admin-token generate (arbiter --api) opened the dest withopen(O_WRONLY|O_CREAT|O_TRUNC). That follows a symlink. A planted~/.arbiter/openrouter_api_key,search_api_key, oradmin_token→ elsewhere link was truncated with the secret. Reproduced:admin_token→secret.txtleft the victim asadm_LEAKED_TOKEN.Path
chmod(0600)after close had the same follow-the-link hole. A planted FIFO could hang the wizard /--apistartup or deliver the secret to a waiting reader.Fix
Shared
write_secret_fileopens withO_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK,fstats a regular file,fchmod(0600)(no path chmod), writes withEINTRretry, andfsyncs. Isolated new helper used bywrite_key_fileandresolve_admin_token.Tests
unit_secret_file— create 0600 file, overwrite + tighten 0644, planted dest symlink does not clobber the target (victim staysdo-not-clobber), planted FIFO refused without hanging, directory dest refused. 5/5 locally (18 assertions) ×3 + ASan + UBSan + TSan.arbitercompiles.Independently mergeable against
main(0456350).git merge-tree --write-treevs main, #321, #323, #326, #339, #342, #343, #344, #351, #354–#364 CLEAN. Does not overlap #363 (atomic_filetmp staging) or #364 (MCP registry tmp). CHANGELOG[Unreleased]is the usual sibling note.Note
High Risk
Changes how API keys and admin tokens are persisted; incorrect open flags or validation could break setup/
--apistartup or leave secrets writable via symlink tricks.Overview
Fixes a local symlink/FIFO exfiltration hole when arbiter writes secrets under
~/.arbiter/. Setup wizard API-key saves (write_key_file) and fresh admin token generation onarbiter --apino longer useopen(O_CREAT|O_TRUNC)(which followed a planted dest symlink) or post-closechmodon the path.A shared
write_secret_filehelper opens withO_NOFOLLOW|O_NONBLOCK, requires a regular file viafstat, sets mode 0600 withfchmod, writes with retry/fsync, and fails closed on symlink, FIFO, or directory destinations.unit_secret_filecovers create/overwrite, symlink non-clobber, FIFO no-hang, and directory refusal. CHANGELOG[Unreleased]documents the behavior.Reviewed by Cursor Bugbot for commit bf38a8c. Bugbot is set up for automated code reviews on this repo. Configure here.