What is OWASP?
Open Web Application Security Project is a non-profit organisation founded in the US to analyse, document and share information pertaining to the most common and severe vulnerabilities in today's web applications. Their goal is to educate us - should we fail to do it ourselves - on the security weaknesses that we emply unknowingly in our applications, how to identify them, and how to prevent them. Put simply, they're a bunch of nights in shining armor helping us write more secure web applications.
Their mission, as they state it, is:
The Open Web Application Security Project (OWASP) is a 501c3 not-for-profit worldwide charitable organization focused on improving the security of application software. Our mission is to make application security visible, so that people and organizations can make informed decisions about true application security risks. Everyone is free to participate in OWASP and all of our materials are available under a free and open software license.
Each year, OWASP publish a list of the web's top 10 vulnerablities that are found across the globe in an effort to educate and strengthen the applications made available to us all.
It's our job as programmers to take heed of the advice and understand what we're doing wrong and to improve on it.
Top 10 - injection
OWASP defines injection flaws as:
Injection flaws, such as SQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing unauthorized data.
I personally feel (and have absolutely no data whatsoever to back this 'hunch' up) that SQL injection is the most common vulnerability out there today; and I'd hazard a guess that PHP applications are the main culprit because although it's easy to pick up, PHP requires a subtle mastery that few acquire before unleashing their code onto the web.
In Java injection vulnerabilties are no-less unlikely, and you'd be risking plenty by assuming that your language of choice could dictate how secure you are. Language features and generic conventions can only go some of the way to protecting what you write; in the end it's down to the developer to not only be aware of what's required to create a secure application, but to be able to prove what they've produced is not vulnerable.
So what does an injection vulnerability look like? Let's build us a scenario: a site that takes a page ID GET parameter and looks up the page content in a database. This web application has a page servlet that deals the content it loads from the database. The code simply reads the request parameter and passes it to a custom DAO that builds up the SQL statement on the fly using string concatenation or something similar. This act of building on the fly and not using prepared statements is what allows an attacker to pass a carefully constructed SQL statement that escapes what you might be doing and then runs “drop database;” or similar.
Here's a typical example:
String pageId = request.getParameter(“pageID”);
String SQL = “SELECT * FROM pages WHERE page_id = “ + pageId;
Line two above is all safe and secure if you only ever pass integers to the page as its GET parameter. If a curious developer saw your 'pageID' parameter and thought “I wonder if I can pass SQL there” you'd be up the creek without a paddle; placing '';drop database; as pageID would run directly on your database and you'd not know until it's too late.
Injection flaws don't stop at databases either. A page can be insecure just as easily if you were to blindly write input straight to the page without validation or sanitising it. Page injection is as simple as:
An even deeper example would be storing input into your model and then displaying that – such as on a confirmation or summary page – without it passing through simple validation routines: removing non-acceptable characters, escaping XML etc (the c:out tag has escapeXml set to true by default, so use JSTL or EL!).
Similarly, if your application needs to write another file to the client and your server-side resource takes in a parameter without validating and ensuring the input is secure you are leaving yourself open to attack. Here are some recommendations to avoiding injection vulnerabilities in your code:
Never, under any circumstances, build SQL statements up on the fly
Never ever, ever, trust your input. Always 'sanitise' by removing non-standard characters; a first name field shouldn't have semicolons for example
If talking to a database, use prepared statements that take parameterised input (by declaring values to be passed as '?' and then setting them via a mutator method).
Utilise read-only users for OS or database access; in the latter make sure you only permit update and insert and certainly NOT drop or grant!
Review your team's code, and have yours reviewed too
As you can see, injection vulnerabilities are quite easy to come across but they're equally as easy to prevent. Do you have any horror stories you've come across that highlight the importance of this scenario? Has code in your organisation sprung to mind when reading this?
Next time we'll cover #2 on the OWASP top ten: cross-site scripting.