Hello! This document will give a general guideline on best practices in building a secure application as well as list and describe commonly used application exploits and how to defend against them.
First and foremost, always enable HTTPS when in production! It doesn’t matter how well written and secure the code is if an attacker can just man-in-the-middle the connection and steal session cookies or inject malicious code.
HTTPS is one of the most important inventions of the past two decades and is responsible for allowing the Internet to grow into the behemoth it is today. It lets users securely connect to servers without having to worry that someone might steal their data along the way. HTTPS should be enabled by default on nearly every website by now as HTTP is inherently insecure but, unfortunately, as of September 2014 only 30% of the most popular websites have it.
Cross Site Scripting (XSS)
Non-persistent XSS is the single most commonly performed XSS attack to date.
Non-persistent XSS is carried out by getting a website to execute attacker-controlled code on the victim’s browser. For this reason it is also known as “reflected XSS”, because the site simply reflects the attacker-controlled code onto the user’s browser. Non-persistent XSS is different than other forms of XSS in that non-persistent XSS does not store the payload anywhere. It is sent without the user knowing (usually through a doctored URL) and the payload is returned in the HTML response.
Typically a hacker will test the site for vulnerabilities with a fuzzer, or by hand testing various exposed parameters by manually trying to inject an alert such as
<script>alert("XSS works >:D");</script>. Once the attacker has a working vector, a crafted URL can be made and masked using redirects on a site they control. From there, they can send the link (ex. “http://meet-singles-now.ru”) and use social engineering to get a user to click on it. This is very common in modern spam, and is often time consuming to perform analysis on when it happens because the victim will likely not believe a site that “looks normal” could have attacked them.
Possible Attack Vectors
In the below example, we will override an enticing link on a site we have determined to be vulnerable to download our botnet client. We will focus on attacking a Windows computer (because of the *.exe), but a similar attack could be done on any system. Suppose the second link on the mysite login page is the login button. The exploited code shown below will download our botnet client to the user’s computer. Since we’re dealing with Windows in this example, we can add some additional testing code (not shown below) to test for common download locations on the users computer using ActiveX, and then use the Run method to run the executable.
Persistent XSS is similar to its non-persistent counterpart with the main difference being that the server saves and permanently displays malicious user data. This usually happens on insecure user profile pages or forum posts. Myspace was a shining example of the horrors of persistent XSS.
Possible Attack Vector
In addition to good coding practices, a Content Security Policy (CSP) can be implemented to add an extra layer of security against XSS and other data injection attacks. CSP is a relatively new W3C specification that allows the server to whitelist which resources (scripts, CSS, images, etc.) are allowed to be loaded by the browser as well as the source of those resources. Every major browser, except for Internet Explorer, supports CSP. You can read more about what CSP can do here.
For more information on how to defend against XSS, read OWASP’s XSS Prevention Cheat Sheet.
SQL injections aren’t seen in the wild nearly as much as they used to be due to increased awareness on how to prevent them. But, in cases where SQL injections are found and exploited, the consequences can be much more serious than XSS. SQL injections occur when malicious user input is incorrectly filtered and then used to build a SQL query that is executed on the database.
Possible Attack Vector
(Fig 1) Consider the following string containing a SQL query
var query = "SELECT * FROM users WHERE id = '"+ userId + "'";
Fig 2) An attacker submits the following as their userId
13' or 1=1--
The user input gets inserted into the query and executed as
SELECT * FROM users WHERE id = '13' or 1=1—-
ow, instead of just returning a single user, the database has given the attacker access to the entire users table!
Also known as Parameterized Queries, prepared statements separate the code (Fig 1) from the data (Fig 2) so the server never executes the portion of the query designated as data. In the above example, if prepared statements were used then the server would literally search for an id of
13 or 1=1--
instead of evaluating and executing it as part of the query.
First, the query is written with placeholders (usually a ‘?’) being used where user-given data would normally be present. That query will then be sent to the database where it waits for the placeholders to be replaced before executing. Now, data can be bound to the placeholders and a second request is sent to the database with the data. The database knows the second request contains only data and will never execute it as a query.
Stored procedures are similar to prepared statements in that the SQL queries are defined and separated from the data. The main difference between the two is that queries in stored procedures are, as per their namesake, stored in the database. An application can call these procedures and send the data without first building a string with placeholders like in prepared statements.
Prepared statements and stored procedures are supported by all major databases and languages. Look them up and learn how to use them before doing anything database-related.
With a database library there’s no need to directly write SQL queries. Using a library that handles turning function calls and objects into queries will be smart enough to protect against malicious input like
13 or 1=1--
by searching for that literal string instead of treating it as part of the query. Slick for Scala is one such library.
Cross Site Request Forgery (CSRF)
Cross Site Request Forgery is used by an attacker to trick users into performing actions on a website that they’re currently not browsing. This happens when the application server trusts the user’s browser and doesn’t check to make sure the request came from a trusted source. Attackers can abuse this trust by crafting requests that match legitimate requests that would be made by an actual user on the web app.
Possible Attack Vector
Because the victim was logged in to the banking website, their cookies and any other identifying information got sent to the banking server when the form was submitted. The server had no idea the request came from a malicious webpage and since the authentication cookies checked out, the request was assumed to be legitimate and funds were sent to the attacker’s account.
Authentication and Session Management
Session hijacking is when an attacker is able to get a copy of a user’s session identifier, allowing them to impersonate that user.
Possible Attack Vector
Session fixation is a clever way to “steal” a user’s session. Instead of getting a copy of a user’s session identifier, an attacker would instead get a valid session by authenticating into their own account. They would then have a victim authenticate themselves using the attacker’s session identifier. If the server doesn’t create a new session upon authentication, the attacker will gain access to the victim’s account.
Possible Attack Vector
Doing Authentication (with and without OAuth)
There usually are libraries and features bundled into frameworks that handle authentication but sometimes you may need to roll your own. Whether you’re using Oauth or writing your own, the two most important things to remember are 1) Always enable HTTPS in production, and 2) Use cryptographically strong hash functions .
Authentication Basics w/o OAuth
Authentication Basics w/ OAuth
Do not store the access token. It’s not necessary and poses an unnecessary risk as the user can just send a new one in the future if needed. Refer to each provider’s documentation on how to implement OAuth as they each do things slightly differently.
Why Salt & Hash?
Always prepare for the worst. Assume the database is going get leaked eventually. If user passwords are stored in plaintext (as-is) or hashed using a weak hash function, it’s trivial for the attacker to get users’ passwords — passwords they probably use on other websites aside from yours.
Appending a salt to your users’ passwords before hashing will, with a high degree of certainty, prevent duplicate passwords for different users from having the same hash. Salting also prevents attackers from using rainbow tables to quickly look-up the plaintext that the hash was derived from and forces them to either spend lots of time/money bruteforcing the hash or just give up entirely.
Choosing a Hash Function
Like with most things in security, use popular peer-reviewed crypto libraries written by people that do cryptography full-time. Do NOT implement any algorithms yourself. And do not ever, ever , EVER write your own encryption/hashing algorithms!!!
The most insecure component in any application exists between the keyboard and the chair. The chair is optional depending on how hip your office is.
Unfortunately, everybody at the New York office uses chairs.
Here are some tips and best practices in securing the project you’re working on from yourself.
Admittedly, having good operational security can be tough sometimes – we’re all human and mistakes can happen. If you don’t think you can follow these best practices, especially if it would have you too pressed for time, try to find someone who can to help out or take over for you instead. Don’t be shy and bring up any concerns you have with your PM.
Web Application Penetration Testing Tools
Both Burp and ZAP are pretty identical in their feature sets – and there are a lot. The most useful feature though would probably be the proxy that lets you view and modify data sent between the client and server in real time.
Directory Bruteforcing Tools