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.
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.
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.
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.
5. When the Ruby library for doing this is written and published, and you're trying to convince people to use it instead of rolling their own, you can refer them to this blog post.
This post is promoting the Proc::UID library, which was apparently only a year old at the time and was not quite finished. The release on CPAN was marked "for testing and review purposes only. Please do not use in production code."
Yes, the author of Proc::UID discussed his module in public. That's not what I'm talking about here, I'm talking about the Ruby community's general love for cut-n-paste instead of actual library writing.
Anyway, compare planet perl and planet ruby some time. The Ruby posts are overwhelmingly "cut-n-paste this code" and the Perl posts are generally "here is a module I wrote". Different cultures.
Anecdotally, most Ruby blog posts I've seen describing how people are "doing it wrong" are just introductions to a gem or plugin on someone's Github account.
Seems to me that you're just taking a cheap shot at Rubyists. :)
- Usenet posts about how to write code correctly
(predated blogs)
- Smalltalk images that contained badly factored code
written by junior people, in all the places where
other junior people would look and imitate
- Years after the heyday of Smalltalk, there's now an
automated tool that will find bugs and critique code
for you, but at this point there are very few who
care.
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.
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)?
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).
(http://search.cpan.org/~tlbdk/Privileges-Drop-1.00/lib/Privi...)