Hacker News new | past | comments | ask | show | jobs | submit login
Sudoedit can edit arbitrary files (seclists.org)
109 points by accessvector on Jan 19, 2023 | hide | past | favorite | 55 comments




I would opt for the Red Hat CVE Database over Bugzilla if you aren't using Fedora, but they all interlink:

https://access.redhat.com/security/cve/CVE-2023-22809

Red Hat has quite a few services under the /security path.




Does this really work? The command is supposed to copy the original file to a temporary file, run the edit command with the privileges of the original user and then copy the edited file over the original. Otherwise what’s stopping an attacker from telling the editor to just open another file?


Yeah I had the same confusion, the linked PDF explains it. Basically sudo determines the list of files to edit after expanding the `EDITOR` variable into separate arguments, and the `--` in the argument list (added by `sudo`) is used to determine where the file arguments provided to `sudoedit` start in the new argument list.

By adding your own `--` in the `EDITOR` variable, `sudo` gets confused and thinks that `--` is the start of the `sudoedit` file arguments and thus happily copies and edits all the files after it.


Incredible! So the problem is not -- but the problem is that it is checking the wrong thing to begin with. Why even parse the string, sudo already had the list of files when it constructed the string..


I mean I agree, I'd say it's mostly just an issue of too much separation, they put the argument array together in one piece of code and then pass it to another piece of code that executes it with the necessary permissions. They don't pass along a separate array of files (or the location in the arguments where the files start), so the execute code attempts to figure out where they are instead.


You're correct but sudoedit itself needs to parse the file list to know which files to copy to temporary files as you describe. So in this case you're tricking sudoedit into thinking you want to edit a different file than the one specified originally on the command line.


Why is this a problem, given that one can easily use sudoedit for privilege escalation already?

edit: I now realize I have confused sudoedit with visudo


I read it at first take as if it was "CVE-2023-32049: 'su' has critical privilege escalation venerability"


Read the link instead of replying based on the title.



Why would one prefer to add sudoedit X to sudoers rather than updating file access privileges of X directly?

Just curious about arguments for this use case.


> Why would one prefer to add sudoedit X to sudoers rather than updating file access privileges of X directly?

Permission complications.

Software may run as user:group, but you don't want to add humans to either, and so you allow them to edit a few files as that user or group from their own account (which also gives you auditing of changes). Some software insists on files (directories) have certain permissions so you're stuff with them.

Or you want a centralized place for permissions, so you put these sudoedit entries in LDAP which can be accessed anywhere in you network, and so you don't have to keep track of individual file permissions on a gazillion systems.


Sudo basically has an ACL-like system where you can specify exactly which users/groups can execute which commands as root. So you can say user foo can execute commands X, Y, and Z as root and user bar can execute commands W, Y, and Z as root, and neither user can use sudo to execute any other command as root. The ACL system isn't for sudoedit specifically, it's a general feature of sudo.

As to why you can't just update access privileges of the file, for most use cases you probably could do that. If you need something more complicated though you'll have to use some terrible ACL implementation like the one in sudo or Posix file ACLs.


I recently got to reading the POSIX.1e (MAC & DAC) draft, and the DAC = ACL part is... surprisingly non-terrible. Still awkward and hampered by its existence as barely-visible metadata smeared over the whole system, as all ACLs are, but not at all the hopeless mess I expected coming from NT. (Even that might’ve been salvageable had Microsoft been willing to publish full documentation of all NT object permissions and mechanisms. Except SDDL, there is no world in which SDDL is salvageable.) Couldn’t make heads or tails of the MAC part, though.

The /etc/sudoers solution does have a usability advantage precisely in not being smeared all over the system. Even if “/etc/sudoers” and “usability” are words not often seen inside a single sentence.


> smeared all over the system

I mean, ACL data is normally stored in filesysem metadata, nothing is 'smeared'.


If you as an administrator want to see where you have granted additional funny permissions, with ACLs your only recourse is to getfacl everything on the filesystem, whereas with sudo everything is listed in /etc/sudoers and classically the group membership in /etc/passwd gives you a pretty good idea. I don’t know if that’s a reasonable thing to want, actually, but it is one that makes me mildly unconfortable with ACL systems in general.


In addition to what has been said already, sometimes it's nice to have guard rails, so you're a little more sure that you're only touching that thing when you mean to.


I wonder if this bug in logic (instead of buffer overflows) would also have been less likely in a different language. Would it have been more obvious in a language where it's easier to work with dynamically allocated arrays and strings?


With my Rust hat on: I don't think that Rust would have solved this. It might have made the code in question easier to understand, as you note, but this kind of error can still happen in any language.


Looking at the patch[1], probably not. There isn't really a lot of complex string handling involved; it's basically just forgetting to forbid "--". I don't really see how any language choice could help you with this.

[1]: https://github.com/sudo-project/sudo/commit/0274a4f3b403162a...


I think there is fundamental design mistake when EDITOR string being badly escaped causing this bug

It has one job

* read file as priviledged user * copy it to temporary file * run editor as unpriviledged user * copy the changed file back

The fact lack of escaping somehow makes sudoedit try to edit file passed in EDITOR variable is extremely shoddy coding.


It shouldn't have to forbid that. The editor and privileged files shouldn't be in the same string. It should just be appending the list of temporary files to the editor command, and running that unprivileged.


You don't even need a temporary file; opening the file directly in sudoedit then passing /dev/fd/N to the spawned edit process after dropping privileges would work (a-la capabilities). But sudoedit being implemented in terms of sudo makes it hard.

edit: apparently things are more complex and sudoedit already runs the command unprivileged; the attack is in filename expansion in sudoedit itself.


Besides the fact that that wouldn't actually have prevented this bug (which you acknowledge in your edit), /dev/fd/N is a linuxism, so wouldn't work on other unices. And has slightly different semantics than the current implementation, where your changes to the file aren't actually updated in the original privileged file until after you exit the editor.


goto statement in something as important as sudo? Seriously? Talk about bad practices.


goto to a cleanup/error handling block at the end of a function is a fairly common C idiom


Don't really see a problem using goto there. Simplyfies control flow and error handling. Assuming we are talking about same piece of code.


I think if you read the kennel's code you're in to a big surprise.


just because something's old doesn't mean it's bad


I would say a more type-oriented mentality would make this kind of bug less likely; thinking of -- as a magic value rather than a different kind of thing from a regular argument makes it easy to forget the distinction, and a mentality where you're "sanitizing a string" is far less reliable than one where you're transforming between two distinct formats.


Good point. A "parse, don't validate" approach to handling the contents of `$EDITOR` would look like `parseEditorEnv :: String -> Maybe ProgramPath`, and that parse should fail.


But that's the wrong thing. The problem is not that EDITOR must be a program, but (apparently) that they're parsing the expansion of EDITOR (along with other stuff) to figure out what file to operate on.


I don't see a change to language, per se, that would have helped, really.

A system with more of an object capabilities model could have helped, though. The goal wasn't really "let the user run their editor as root (when they ask for it)", but "let the user work with this particular file from their editor (when they ask for it)".


On reflection, I think C is a language where this kind of error is less likely. In languages where it's easy to cram strings together and parse the results, people are more likely to do it. Those things are a bit of a pain in C, so people are more likely to do things another (and in this case better) way. Of course, that was obviously no guarantee.


Doubtful, failing to sanitize your inputs plagues memory safe languages too.


It's kind of tiring to hear about memory safe languages (mainly rust here) being put on a pedestal, as if it will solve all our software woes.

Not to mention, C++ /can/ be memory safe if you use memory-safe routines.

I'm just waiting for articles to come in, this year.. "why 2023 was not the year of Rust". Not hating on Rust - just the evangelism.


Ironically, even C has the tools to avoid this. You just need to be running OpenBSD: https://man.openbsd.org/unveil.2


I don't think that works here. The editor is supposed to be able to access other files.


This is more of a shellshock-like bug than anything complicated involving memory. Just a really stupid misconfiguration oversight.


Consider this a prompt to review your /etc/sudoers for any utility whose behaviour is modified by environment variables in the env_keep list.


I don't think that's what's happening. sudoedit does NOT run the editor as root, it copies the file to a temporary as root, runs the editor as you, and copies the temporary over the target file as root when you're done editing it (at least it's supposed to).


Looks like a misclick, but unsure which comment was intended for this reply.


Yours.

The editor cannot be tricked into editing the wrong file as root by environment variables, because it is not running as root.

The security is an actual flaw in sudoedit, the wrapper script, not a fundamental issue with the environment you pass to the command.


I did not mention an editor, so that reading doesn’t follow. Other comments certainly did and could be wrong in the fashion you describe. However, I did not write them, so I feel no need to defend them.

My point is simply the actionable generalisation of your followup, the substantive part of which I don’t even disagree with. In this instance the utility is the wrapper.


Is there a patch, or more detailed explanation of what causes this?


Ubuntu shipped the patch three days ago. The output of `apt changelog sudo` on 22.04 LTS:

  sudo (1.9.9-1ubuntu2.2) jammy-security; urgency=medium

    * SECURITY UPDATE: arbitrary file overwrite via sudoedit
      - debian/patches/CVE-2023-22809.patch: do not permit editor arguments
        to include -- in plugins/sudoers/editor.c, plugins/sudoers/sudoers.c,
        plugins/sudoers/visudo.c.
      - CVE-2023-22809
    * SECURITY UPDATE: DoS via invalid arithmetic shift in Protobuf-c
      - debian/patches/CVE-2022-33070.patch: only shift unsigned values in
        lib/protobuf-c/protobuf-c.c.
      - CVE-2022-33070

   -- Marc Deslauriers <marc.deslauriers@ubuntu.com>  Mon, 16 Jan 2023 07:36:33 -0500
There is a detailed explanation on the sudo website: https://www.sudo.ws/security/advisories/sudoedit_any/


There's a detailed writeup mentioned in the post https://www.synacktiv.com/sites/default/files/2023-01/sudo-C....


It shells out to the EDITOR environment variable, which is controlled by the less privileged user.

In this example they inject running an editor against another file.

I'm guessing you can put arbitrary code in there or point it at a locally controlled executable too. But I'm not sure. Maybe sudoedit puts more scrutiny on that variable than most, non-security programs. At any rate many text editors have lots of modules and scripting and can presumably load and execute code as the privileged user.

The workaround is to change the sudo config file to remove the EDITOR environment variable and a few others.


> At any rate many text editors have lots of modules and scripting and can presumably load and execute code as the privileged user.

Sudoedit does not run the editor as privileged user, that is kinda the whole point


I moved to https://man.openbsd.org/doas long ago.


Is doas safe about this exploit or does it have the same problem ?


doas has no "doasedit". It's a lot simpler than sudo, on purpose.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: