Archive for February, 2008

ruby > perl

 my $status = $self->{'status'}; $self->do_something_with($status);

 self.do_something_with(@status)

Untrusted webapps

I’ve been meaning for a while to write a bit about a design tactic I’ve been
using a lot lately: namely, using the “proxy” and “session facade” design
patterns to create a security boundary between a public-facing web application
and critical infrastructure.

Since I work in a systems group, a lot of the code I write talks to extremely
sensitive services like our Kerberos KDC, a.k.a. “the database that holds everyone’s network
password.” We have to guard this system pretty closely, since an exploit on it
basically means root access on every server on the network.

I don’t trust a web application (especially one written by me and a handful of
other folks with dozens of other things to think about and work on) to
directly manipulate this data. In fact, I don’t even want the code that
actually messes with it running on the same physical host as the web server,
since there are altogether too many places where an attacker can get at a
public web application.

So, we separate the system into two main pieces: the web front-end and a
“trusted” back-end system which can access the sensitive data. The web UI is
considered “untrusted”, and must accept whatever level of access the back-end
gives it.

The key re-usable pattern that comes from this is the combination of a
client-side “proxy” object, which hides the network transport and session
handling logic from the web application, and a server-side “session facade”,
which insures that access controls are maintained according to policy.

The most recent example of such an application was the online password-reset
system I built last summer. We’re currently re-writing and expanding that tool
to cover account creation as well, but the basic architecture is the same.

For the password-reset system, the client proxy is a Ruby class that serves as
a non-database-backed model. The first version of the system used DRb, while
the new version is using XML-RPC, but the application logic doesn’t see the
difference, since the proxy class encapsulates all the low-level details.

On the server side, we’re using mod_perl in order to get access to all the
CPAN goodness for Kerberos and LDAP directory manipulation. The session facade
keeps track of what privileges each user has earned (both persisten and
per-session), and complains loudly and ends the session if the webapp makes a
request for which it hasn’t earned access rights. Since a session is
particular to a single user, each can only manipulate that user’s account
data.

You end up with a few more moving parts — in particular, making sure that
user sessions don’t time out on the back-end while active on the front-end
takes a little bit of coordination — but a very robust, loosely-coupled
system. Plus, even if our web front-end gets 0wned, only accounts that are
actively being reset after the compromise are themselves at risk.

Miscelleny

It’s been an awfully long time since I posted. In the interest of keeping myself from getting too much blogger’s cramp, I’m gonna just throw out a bunch of the stuff I’ve been working on lately without much sorting:

Work: been doing a lot of Perl hacking lately. It wouldn’t hurt my feelings to never have to write ‘my $self = shift;’ again, but it’s not too terrible to just set up some editor shortcuts and soldier on. (Did that sound a bit like the Java apologists and their defense of the need for IDEs in modern Java development to anyone else? Oh, well.) Overall, though, I’ve been reminded of just how rich and broad CPAN is — before having to think too deeply about how to implement a non-trivial algorithm or piece of infrastructure, I’ve re-learned to just check CPAN, ’cause there’s probably already a module there that does it, whatever *it* is.

Home: made a big batch of sausages this weekend, loosely based on the recipe from the [Charcuterie cookbook](http://www.amazon.com/Charcuterie-Craft-Salting-Smoking-Curing/dp/0393058298/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1203358472&sr=8-1]) that Hannah got me for my birthday. They were, in a word, delicious. Easy (if a bit messy) to make, and absolutely positively better than any store-bought sausages I’ve ever had. Of course, they should be: I used better cuts of meat than I would imagine a large-scale butcher would, and ate the damn things within 24 hours of making them.

Nice for a change

Some time around July of ‘06, I wrote a quick one-off script for the library here at Reed. It does some very basic page scraping and link-traversal to build lists of URLs to serve up through our authenticated proxy server for remote access.

We had some reports come in early this morning from users at home who were having trouble using the proxy with certain on-campus servers, which I investigated and found to actually be due to a simple configuration error. I fixed that error, re-ran the crawler, and saw that things were working properly again.

Since I hadn’t looked at the actual code in quite a while, though, I figured it would probably be a good idea to fire up the ol’ editor and see what atrocities might be lurking, and maybe do a bit of refactoring. Five minutes later, I closed the editor buffer without having changed a single line of code.

Why not, you may ask? Simple: *nothing needed changing*. The code was concise and understandable; it even had logging and error-checking in all the right places. More importantly, it had been working pretty much as expected for nearly two years now, silently chugging away and keeping that list of links up-to-date without complaint.

Now, that may not sound important to some people, but I think most of my fellow techies will understand just how rare it is for bit-rot to hold off that long, especially with an application that runs automatically every day, depends on input from a number of mutable sources, and sees constant use by a few hundred users.

It made me feel pretty good starting out the day, no matter how trivial a thing the application itself might be. *Something*, at least, was happily working as expected, and with any luck, no one will have to fire up their editor and look at that code for another couple of years at least.