Re: TOCTOU symlink race bypasses --operatingdir confinement
Benno Schulenberg <[email protected]> Wed, 29 Apr 2026 10:20:34 +0200
| Newsgroups | gmane.editors.nano.devel |
|---|---|
| Message-ID | <[email protected]> |
[Do _not_ answer to me. Answer only to the list.] Op 28-04-2026 om 18:11 schreef zero_o: > Thanks for the quick response. > what exactly is the threat model? > Fair question. Please use proper email quoting. And stop using HTML mail. > The write path (write_file, line 1790->1871) is where > unintentional overwrite occurs. Consider: > A shared build directory -- /tmp/ci-sandbox/, writable by multiple users on a > dev server. A script confines nano there to edit a config file before feeding > it to the next build step. Really? Several users share the same sandbox? That is a recipe for disaster. Certainly each user should have their own sandbox. And during continuous integration a user needs to interactively edit a config file? Never heard of that. Or is the editing also scripted? If so, how? > Another user on the same machine races a symlink swap > during the save. The file the victim intends to save into the sandbox gets > written to a completely different path outside the confinement. > Concrete overwrite targets reachable via the write-path race: > > ~/.bashrc (code execution on next shell) > > ~/.ssh/authorized_keys (persistent remote access) > > ~/.profile, ~/.config/autostart/* (code execution on login) > > These are all files the nano user can legitimately write to, and they are > outside any reasonable --operatingdir confinement. Sure. But what happens when a random config file that the user edits overwrites one of those files? The most likely result is a bunch of faults and failures -- unless the attacker can also insert relevant codes or commands into that config file. How would they do that? > I agree that a private directory is safer, but --operatingdir is explicitly > marketed as a security boundary. There is no mention in the man page of security. And "marketed"? We're not marketing anything. > The man page says it restricts file access "to a specific directory > and its subdirectories". You quote something that is not in the man page -- not in exactly this form. You are a stupid LLM. > The code calls outside_of_confinement() and produces error messages like > "Can't read file from outside of %s" -- language that clearly intends to > enforce a restriction. Conceded. > If the feature makes a security promise it cannot keep, that's a bug worth > fixing even if the threat model is narrow. As said: there's no actual promise. And the threat model is _extremely_ narrow -- existing only in misconfigured setups. But yeah, a TOCTOU is worth fixing. Show the fix for the write path too. > The attached PoC currently demonstrates the read path (because reading > /etc/passwd is a harmless way to show the bypass works). I can adapt it > to demonstrate the write path with actual overwrite if that would help. > > The minimal fix (one realpath() call, reuse the result) costs almos > nothing and closes the window entirely, regardless of whether the > directory is public or private. > > Would a write-path PoC be useful? Sure, when it includes command injection. You seem to have endless time. Benno
OpenPGP_signature.asc
(application/pgp-signature, 840 B)
-----BEGIN PGP SIGNATURE----- wsF5BAABCAAjFiEEFo5vQpe/16ea/USWUUu+Lrjhlh8FAmnxv1MFAwAAAAAACgkQUUu+Lrjhlh+V lw/9HY5AC09EXhq1Lu0qn6QktPRpp234SK8psLg/wVlTppgbF1Q+J8s8z/5bYnI15KvXpC4Q8kdv FU24PnOzy2UCWxShE+dNNePOSVJVrZAp7+p3PvpP220oWTSY2CiMWb6FR1dCb8fAjlJz5oVp1lSH f4xRc6O/8hxojABTIvq/SbHD9DRSngbdvg0ZjH9UCikOCUldBW9OEjrjHL9x88Zq8WloF9PBoWVg SMcirhMC5EMWMcgy8vRguZ3lWcXrl3fbViu7TwPcWBF5gbxlEbFlBkZYiMJjPXsWfBcdn5lsD4lx jGAz7GOLQPCyoLdAxqGEF8ilQRJDNAZV2JySTYCgMdZyzvValM49rsbQkgJdXRc8PrjQ308Erucn BJRr6/z1rHMbSiGqCJ+7rbKrrJEddimAjMmAiWZRY9FlQlXYe4lgS3xC/WjC8ZJGioy4GQ6fbq0c dIRr43NHbnLcJ+SoIGAAYxdNzct6pyl0mkVWHWP33r9WN3C2bq4jB/Glmfu+8ollSlDGuLYlC6l5 dkqnkgbTqcvzzImbWnc3Q9OsSSev06gKD6HvJ3mn8fC9SNymG1YrsYPGMEQYFqoMrYM/U8Ug9yvg LqByx0qsFpiRWhdmL6awhWgi7iQjof+YR6L7yGT/clMUEtjuZz6P3EMGG2R1ieK+xv8uysvHhHWU Mx0= =MiTj -----END PGP SIGNATURE-----