Business today is digital. Software-dependent. That means nearly every company is exposed to a growing number of potential vulnerabilities. Major system hacks — anxiety-inducing and costly to fix — regularly make the news. Hacker's preferred target: the application layer. Fortunately, protecting your application layer is straightforward.
Here’s a look at what hackers see, how they break in, and what you, the web developer, can do to prevent it.
What hackers see: They know speed is important to your site; that the page load time matters for SEO and the user experience. They practically salivate when they realize you’re using the far-less secure HTTP rather than HTTPS for some pages. Guess what: you just made a hacker’s day.
How hackers get in: Session hacking allows users to get into your application. Hackers can sniff inline (man-in-the-middle attack"), "blind" hijacking (which guesses the responses of the two machines), or use source-routed IP packets to steal a session.
How to prevent: Use HTTPS for everything! Make sure your cookies use the secure flag to instruct the browser to send cookies only in HTTPS. Use POST for sensitive information. Do a SSL Test every few months: https://www.ssllabs.com/ssltest/index.html
Securing User Account Names
What hackers see: You know those sites that allow you to reset your password? You put in your username and receive a message saying email sent to userx. If a hacker does this, the email tells him (I’m using “him” generically but research shows most hackers are male) knows that a user has an account with you.
How hackers get in: They already know user passwords from other sites that someone else has hacked or from information they gleaned about you from social media. Hackers just need to know you have an account on this site and what your username is. Once they know you have an account, they simply check the hacker password database they stole from some other site and try to use.
First, they’ll test to see if the site returns username not found.
You can see that the response has an “error” class. Hackers know that a username cannot found. They now know they can test who has an account. They grab their database of possible usernames the start testing form matches.
The response above has a “success” class. The hacker knows which account names or email address exist in your system. The first step in hacking this site.
How to prevent: Never reveal user names and email addresses, and lock user accounts after five failed attempts (or fewer depending on the sensitivity of data). Make your message generic. Something like:
The hacker won’t be able to verify account names and in frustration will move to another site that’s easier to hack.
Consuming Hash and Salt
Hash algorithms are one-way functions that turn any amount of data into a fixed-length "fingerprint" that cannot be reversed. Salt is a random string appending or prepending before the hashing. Hash and salt lets you combine two methods for obscuring passwords to maximize security.
You might think, "our data isn’t sensitive so no one will want to steal our passwords. And users reset their passwords every six months anyway so why not just store the password and forget about this hash/salt thing?"
Here’s why hash/salt matters.
What hackers see: A treasure-trove of passwords. Let’s say a hacker steals your user and passwords table without hash/salt. You might have just shared your user’s Amazon password. Or maybe their online banking password. Essentially, you’ve just given the hacker a backdoor and set your user up to be hacked somewhere else.
How hackers get in: You don’t put any salt on that password!
An example of how to break a password hash:
Your Password: mysecurepassword
Your Hash: 50b9798b5454b52f93f37b15ad4680cd
But you can’t stop there. Here’s why: if someone else used the same password, the hacker would be able to figure it out. Also, hackers know the passwords of other users from their database of previous hacks so it might be quite easy to decrypt yours.
Here, try to break my hash: https://crackstation.net/
Isn’t it easy to crack a hashed password without salt? By adding Salt to the password before it is hashed, you’ll bolster protection.
Your Password: mysecurepassword
Your Salt: HdOWpvOVLjlcMGC1G_Ot
Your Salt and Hash:a5a29768b922864694ea65119bbac271
Try it again with salt: https://crackstation.net/
How to prevent: Never store the password itself. Never. And don’t create your own system for hash/salt. Use bcrypt and scrypt instead.
Accepting Any Form Input
How hackers get in: Even if you use negative validation or blacklisting in custom code to reject known, dangerous values, you can’t think of everything. What happens when unknown values are not planned for? Suppose you’re filtering out the “<script>” tag? Would that be safe? Probably not. What if you enter <scr<script>ipt> ? Nope. The hacker just got around your negative validation filter.
Some possible outcomes of accepting any form input:
Cross Site Scripting (XSS): XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.
SQL Injection: A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application.
Buffer Overflow: A buffer overflow condition exists when a program attempts to put more data in a buffer than it can hold or when a program attempts to put data in a memory area past a buffer.
How to prevent: Use a web frameworks validation to push validation to the edge. Don’t allow it into your custom code. Whitelist when you can. It’s better to control what is going in than plan for what isn’t going in. And don’t reflect input back to a user. The more a hacker can see what you’re filtering, the easier it will be for him to figure out your methods.
(Owasp explains all input validation hacks here.)
Binding Parameters for Database Queries
What hackers see: They know you want simplicity. Why should you add more code and make it harder to read rather than writing the database queries as simply as possible? Stored Procedures should save you, right? Wrong.
How hackers get in: This cartoon from XKCD Comic brilliantly (and painfully) shows how a user can easily drop one of your database tables. Imagine what else they could do if they get this close to your application?
How to prevent: Bind all data (queries and stored procedures). Use your platform’s mechanisms to protect your site. Push user data processing to the edge of your stack.
$result = db_query('SELECT n.name FROM users n WHERE n.name = :name', array(':name' => $name));
Here’s an explanation from IBM on DB binding:
“A bind variable consists of a variable indicated by a placeholder character, such as a question mark (?), :name, or @name. The placeholder character depends on the SQL database server that you use. You provide the actual value of the placeholder at runtime, just before the SQL statement is executed. When a bind variable is passed as an argument to an SQL prepared statement, it is automatically escaped by the driver. The resulting escaped strings treat the variable as user data and cannot be interpreted by the SQL database server as an SQL statement.”
Take These Steps to Ward Off a Breach
Want to minimize the chance hackers can easily access your site? Add the following items to your important to-do list, and follow the advice presented throughout this article.
- Assess your risk tolerance and level of data security
- Go through a threat and risk modeling process
- Set up processes for reviewing security on a regular basis
- Perform peer code reviews
- Patch the OS
Frustrate hackers enough and they’ll look for an easier target.
Want to know more about online and IoT security? Check out these blogs by ICS CEO Peter Winston.