Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^11: Best way to write to a file owned by root?

by afoken (Chancellor)
on Mar 15, 2017 at 22:12 UTC ( [id://1184782]=note: print w/replies, xml ) Need Help??


in reply to Re^10: Best way to write to a file owned by root?
in thread Best way to write to a file owned by root?

Would you care to find out the hard and painful way?

That's exactly the point. "It's my machine, only I use it, so I can take some evil shortcuts" works, up to a point. We don't need a very clever hacker if you run a local webserver with a /etc/hosts rewriting CGI and make that accidentally available to the internet, e.g. by misconfiguring the DSL router to forward port 80 to the wrong machine, or simply by connecting it to a network that actually uses non-private IP addresses (quite common in universities) and at the same time not limiting the webserver to localhost. Such accidents happen. Or worse, pass your "/etc/hosts hack" to someone else who does not understand why access to the CGI must be limited.

Now, imagine one little error that allows overwriting /etc/passwd instead of /etc/hosts. It's like connecting an unpatched Win95 machine to the internet.

Yes, you could do a lot of work to prevent that, in a setuid program. But then again, one typo may open a hole. Perhaps even without any warnings or errors. Experience shows that programs grow, and complex programs tend to have very unexpected errors. Which gets quite worse quite fast if the program runs setuid or setgid. sendmail and bind are examples of complex, hard to maintain programs that have a huge trail of security problems.

Privilege separation prevents programs from doing bad things. Not perfectly, but better than running everything in one program. Giving out only the required privileges ("principle of the least privilege", see the OpenBSD PDF link elsewhere in this thread) prevents gaining privileges, like a parser running amok suddenly overwrites /etc/passwd just because it was fed invalid data. And finally, combining lots of small tools for a big job is one of the strengths of Unix. Small tools tend to have a manageable amount of source code. That allows to peer review, test and verify the tool up to the point where you can be very sure that the code does not have bugs.

Yes, it might look like overkill for editing /etc/hosts. Nevertheless, it's not that hard to do it right instead of doing it quick and dirty. Unix makes it quite easy, because you can easily drop privileges.

I've already linked to postfix, let me also recommend reading the documentation of the Unix tools made by djb (qmail, djbdns, daemontools, and ucspi-tcp) Yes, the documentation is terse, you won't find a word that is not absolutely necessary, and you should read it more than once to fully understand it. The code looks like a mess, but again, it's terse, every single character has its purpose. And apart from djb insisting on errno being defined as extern int errno (which is only one of many possible implementations), it is in fact very clean. All of the tools make great use of the core features of Unix to build secure, networked software.

A very cheap trick for the validator in the privileged service from Re^4: Best way to write to a file owned by root? is to run the validation of the new file as unprivileged user. Because the service runs as root, it's easy: fork(), and in the child process, open the file to be validated as file descriptor 0 (STDIN), close all other handles, set euid, fuid, uid, egid, fgid, gid to nobody/nogroup, perhaps chroot() and chdir() to an empty, unwriteable directory, then exec() the validating code. The privileged worker process waits with a timeout for the validator to return either successful (exit code 0) or not successful (any other exit code). If the timeout (alarm, sigaction) occurs, kill the validator and treat the validation as failed. If any evil input makes the validation code run amok, it runs in an empty chroot as nobody, so it can do almost no harm. If the validator hangs, the timeout will kill it soon. No halting problem to be solved. Error handling in the validator code is also very easy. If anything looks fishy or can't be parsed, just die, ASAP. The OS will clean up after your process.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1184782]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (1)
As of 2024-04-18 04:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found