Join 3,512 readers in helping fund MetaFilter (Hide)


Server security: creating separate silos for applications & hashing passwords help
November 16, 2011 12:13 PM   Subscribe

Can you help me understand how to approach a couple issues of server security. (1) I want to run things in 'silos', so that if someone from the web has hacked and has code level access to example.com/blog they can't query the db of example.com/app (2) If they do get access to a user database, how do I make it harder for them to figure out passwords (beyond just storing them as md5)?

I'm thinking one thing that can be done is to actually encrypt passwords and put the shared secret in a place that can't be accessed by anything except the login code, something like that?

This would be based on linux & apache and most of the code for now would be php/mysql. Thanks for any info!
posted by the mad poster! to Computers & Internet (13 answers total) 1 user marked this as a favorite
 
salted password hashes are the correct way to store passwords.
posted by jannw at 12:17 PM on November 16, 2011


By asking this, you've taken the first important step: admitting that you're in way over your head.

1. isolating page-to-page is only slightly difficult with modern web servers; once you've let the attacker run code on your server, he/she generally will have access to everything that the user account (running the web server / app) can see. So the trick is, if you want to increase that isolation, set up apache to run multiple VirtualHosts and suexec everything in each host as a different user.

2. never store passwords in plaintext and never hash them without salt.

3. the shared secret is as vulnerable as any other piece of code on your server; the server has to run that code to process the login, which means the server can get to that code. Again, as mentioned in #1 above, you can gain some isolation by using different user accounts, but once you sit down and draw it out, this doesn't really work that well for the purpose. (You have to, in every page, validate the user login token somehow, and that'll mean talking to the login code.)

4. user-level isolation and secure code doesn't do anything if you leave the rest of the server unsecured. Understand your vulnerability surface.
posted by introp at 12:27 PM on November 16, 2011


salted password hashes are the correct way to store passwords.

Thanks. But if the salt is in the code somewhere, and the person has access to both the code (ie. by executing code that can read the config file, or other container of the salt string like
'echo file_get_contents("config.php")'
) and the db, the advantage of the salt is negated right? I guess we need to store the salt someplace that can't be read by most of the scripts

Here's another article I found advocating bcrypt just cause it's slower than md5...
posted by the mad poster! at 12:28 PM on November 16, 2011


You need to hash and salt your passwords with an effective hashing algorithm.

Passwords hashed with an unsalted MD5 (or SHA1, etc.) can be retrieved using a rainbow table - i.e. a huge pre-prepared list of hashes for words. For that matter, you can often google for common MD5 hashes and find what hashes to them.

Salting prevents this - it's impractical to create a rainbow table for every salt/password combination.

However, attackers can still use a dictionary attack, and if your users are using insufficiently secure passwords (as most users will be), then their passwords will still be retrieved.

The solution to this is using bcrypt instead of MD5. MD5 is designed for speed - exactly what you don't want. Bcrypt is much, much slower - not a problem for your code, since you're not checking billions of password combinations, but definitely a problem for an attacker.

See this StackOverflow question for implementing Bcrypt in PHP.

Don't encrypt the passwords - that just means that they can be decrypted. A hash is a much better solution.

On preview - I see you've responded on salts. It's certainly not wrong to make it harder for attackers to find the salt, but it's not critical either - the main advantage is to prevent rainbow table attacks, and that works even if the attacker knows the salt (because they still have to do all the computation to build the rainbow table - no easier than a dictionary attack). You need to assume that an attacker will have all of your secrets, if they are able to get your code and your database.
posted by siskin at 12:35 PM on November 16, 2011


The salt isn't in the code; it's randomly generated and stored in the DB with the hashed passwds. It purpose is to make there be (typically) 26^2 possible hashes for each cleartext, to confound reverse lookups by bad guys who get a copy of your DB.
posted by nicwolff at 12:36 PM on November 16, 2011


Bcrypt is good. If someone is trying to crack password from a file or database on your server you want the process to be as slow as possible for them. When someone logs in, the extra time for a comparison won't cause you any problems.

Salted hashes should protect you against rainbow tables. Rainbow tables are huge lists of precalculated hashes. Without a salt your passwords may be almost instantly looked up from the list. With the salts they are all different to a direct hash, and it's not feasible to pre-calculate them.
posted by BinaryApe at 12:38 PM on November 16, 2011


So the trick is, if you want to increase that isolation, set up apache to run multiple VirtualHosts and suexec everything in each host as a different user.

Ok this is helpful. So if I get a VPS or dedicated server that lets me configure apache I can setup something along these lines, where each database/directory tree/etc is totally sealed off from the other?

Again, as mentioned in #1 above, you can gain some isolation by using different user accounts, but once you sit down and draw it out, this doesn't really work that well for the purpose. (You have to, in every page, validate the user login token somehow, and that'll mean talking to the login code.)

Not sure I follow what you mean here? What I'm trying to do is if one web application does get hacked (the blogging software, for example), not expose the other stuff on the server to whoever has hacked into *that* app
posted by the mad poster! at 12:39 PM on November 16, 2011


Don't encrypt the passwords - that just means that they can be decrypted. A hash is a much better solution.

good point!
posted by the mad poster! at 12:40 PM on November 16, 2011


To explain: You can make a "login.example.com" whose only purpose in life is to handle user logins. The user logs in there and is then redirected to "app.example.com" or "blog.example.com", but how does each page on either of those sites verify that the HTTP request it just got is, in fact, a valid logged-in user? It has to check the cookie the browser provided with the request and a local login token it has kept. But we've said above that "login" and "app" can't see each other's files; so you have to poke a small hole in the sharing, either by allowing back-channel communication (say, non-port-80 requests that aren't routable to the outside world) or by allowing a shared data store (directory, database, etc.).

Once you do that, any significant compromise of "app" or "blog" can use that hole you provided: it can overwrite login token files, make back-channel requests on its own, etc. So while it buys you something, it doesn't buy you as much as you'd maybe think. There are hundreds of isolation schemes like this, and they likely all have some merit when seen within the larger system: it's all a matter of trade-offs.

The nature of the questions you're asking indicates that you've just started climbing the mountain that is server/app security. You'll discover it's a really wonderful, intriguing, and complicated mountain (and that there are always attackers out there smarter than you).
posted by introp at 12:51 PM on November 16, 2011


It's certainly not wrong to make it harder for attackers to find the salt, but it's not critical either - the main advantage is to prevent rainbow table attacks, and that works even if the attacker knows the salt

Okay I just got this. Basically they have pre-generated hashes, but they've not been generated with our salt, so those can't really be used

introp: yeah the 'protected login script' thing doesn't work I just realized, cause with every query to the page you have to re-check the credentials.

I've spent so much time working off of things like facebook, wordpress etc. that handle authentication against their systems that I never really worked on figuring out authentication related issues for myself.
posted by the mad poster! at 1:02 PM on November 16, 2011


Okay I just got this. Basically they have pre-generated hashes, but they've not been generated with our salt, so those can't really be used

You've got it, except that ideally each password is hashed using a different salt, so that the attacker can't even generate a custom table to crack your password database.

It's important to understand all this stuff, but please think twice before implementing it on a live service. Security is gnarly and there are so many pitfalls to catch out all but the most grizzled old hands that it's really better to leave it to them. There are plenty of libraries and existing code which has been pored over by world-class crypto nerds looking for the slightest weakness. Unless your project is just for learning, best to use them instead.
posted by Busy Old Fool at 2:02 PM on November 16, 2011


For PHP, I'd use phpass instead of rolling your own crypto. It implements all the gory details of crypt() with blowfish internally and handles proper salt generation for you.
posted by xiw at 2:10 PM on November 16, 2011


Thanks folks. Here's a good article I found from via the stackoverflow above that explains things fairly painstakingly (if snarkily) Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes

As for the isolation thing, I'm going to give up on doing that personally for now.. if anything needs to be genuinely sealed off (high priority) then I'm going to put it on its own server account at a 3rd party and then point a subdomain at it. And then if the project takes off, down the line, hire someone to professionally setup the SUexec/virtualhosts situation
posted by the mad poster! at 6:38 PM on November 16, 2011


« Older Im 21 years old, depressed, st...   |  Help convince me that it's oka... Newer »
This thread is closed to new comments.