

Things You Don’t Know About User IDs That Will Destroy You - ice799
http://timetobleed.com/5-things-you-dont-know-about-user-ids-that-will-destroy-you/

======
jrockway
This blog post shows an interesting difference between the Perl community and
the Ruby community. The Ruby community lives to write long blog posts about
why you are writing code wrong. The Perl community just makes a library
everyone can use to avoid getting things wrong in the first place.

([http://search.cpan.org/~tlbdk/Privileges-
Drop-1.00/lib/Privi...](http://search.cpan.org/~tlbdk/Privileges-
Drop-1.00/lib/Privileges/Drop.pm))

~~~
boundlessdreamz
Interesting point, but I think of it as teaching a man how to fish and giving
him fish. If you read and understand this blog post,

1\. You can write your own lib

2\. You can spot bugs in other programs regarding privileges

3\. You have an understanding of how privileges work and can transfer that
knowledge to other programming languages/problems.

4\. When you use a third party lib for, say dropping privileges, you can
actually verify that they are doing it right because you actually understand
what is going on and what is needed.

~~~
jrockway
Consider the case where the blog post is not entirely correct. How do you tell
everyone that cut-n-pasted the code from the blog to fix their apps?

You can't. At least with libraries, someone can report a bug or send a patch,
and you can release a fixed version. Any reasonably competent developer will
eventually notice the new version and upgrade the module. Problem fixed.

With a blog post, there is no reasonable way to push out new features,
patches, bug fixes, security fixes, etc.

~~~
boundlessdreamz
You are thinking in terms of code. I'm thinking in terms of knowledge.

What you should take away from the blog post is not the code. It is the
knowledge. It has given a good starting point, on doing your own research.
Just using a lib usually never leads to that.

~~~
stcredzero
Using a lib can get things done. Sometimes you have to get things done now and
have to come back to understanding the problem in depth later.

Debugging through someone else's library is often a great way to do that.
(Provided your language/environment's debugging support is good enough.)

~~~
GHFigs
_Sometimes you have to get things done now and have to come back to
understanding the problem in depth later._

This is a great way to create whole _new_ problems.

~~~
jrockway
Do you know every implementation detail of the database management system you
use?

The fact that proprietary databases exist means that you _can_ use libraries
without understanding all the code in them.

------
tptacek
Another way to look at this: if you're typing "setreuid" into your code,
you're doing it wrong. Most networked Ruby programs don't need to run with
superuser creds in the first place. Factor the need out of your code.

The threat model in this post is a bit dated, too. The EUID is insecure if
(paraphrase) "you can execute arbitrary code in the process, because you could
just execute setuid()". That's true, but it neglects the fact that if I can
run arbitrary code in your process, you're fucked anyways:

* Localhost nobody->root is a speed bump on most Linux deployments.

* If your app works as "nobody", so does an attacker with "nobody" creds.

* "Nobody" has network access, can talk directly to your database, and to every insecure box in your data center.

------
Hexstream
Is the complexity of the *nix IDs completely warranted or can it be mostly
attributed to historical precedents? Would there be a way to significantly
simplify it without really reducing flexibility (I'm not necessarily looking
for a backwards-compatible way)?

~~~
jrockway
The problem is not so much of user IDs, but rather how UNIX implements
security. "root" can do privileged things, everyone else can't. For example,
only the root user can listen on port 80. These rules are hard-coded in the
depths of the OS, meaning you have to work around them.

The problem is that you don't want your process-that-listens-on-port-80 to
have all the other permissions that "root" does. So you have to drop your
privileges after binding port 80, resulting in the complexity of effective and
real UIDs (and GIDs).

The solution is fine-grained access control. You don't want to say "run this
app as nobody", you want to say "let this app connect to the MySQL server,
write to /tmp/my-app, and load shared library foo". Could you implement a
system like this? Yes. (SELinux is a start.)

But really, it is time for UNIX to die. "Worse is better" is getting old, and
UNIX can't be fixed. Someone needs to implement a real OS (and provide UNIX
compatibility so users can easily migrate).

