Imagine building your dream home: You’ve taken painstaking care to add unique and super expensive fine touches. You’ve bought the top tier hardware and fixtures. You’ve put up shiplap for some unknown reason (no judgement), and fill it with your most priceless, prized possessions. And then you just leave the door wide open.
You wouldn’t do that though, because that’s ridiculous, isn’t it? But that’s exactly what it’s like to have an application without the proper level of security in place. You can have the best, most beautiful, responsive UI built on the latest and greatest frameworks, but if it isn’t secure, it will cause you some serious grief down the road.
An unsecure website is an invitation for hackers to exploit your weaknesses for their gain. Vulnerabilities can, at best, lead to exposing sensitive data, data breaches, lawsuits, loss of clients, loss of revenue, male pattern baldness…suffice it to say, the consequences can be devastating.
A solid first step in putting together a penetration testing plan of attack is to take a gander at the Open Web Application Security Project’s (OWASP) top 10 application security risks.
Whoa, ok. That’s a lot to unpack. The world of security testing is a broad one, so for now we are going to focus on the first item in the list, which is one of the most prevalent AND easy to test security flaws: Injection.
Have you received an email from one of your favorite retailers politely informing you there was a data breach and you must now change your password? Followed by a friendly and not-at-all-concerning suggestion to enroll in a credit monitoring service?
Chances are that company found themselves on the receiving end of some good old fashioned injection. Some heavy hitters that have been
impacted in recent years include Target, LinkedIn, Yahoo, Equifax(!). These companies have like, a gazillion dollars to throw at security prevention, and still hackers have found and exploited their vulnerabilities.
RIGHT. SO WHAT IS IT?
Injections can be SQL, NoSQL, LDAP, CLRF and any other ways that a hacker can take advantage of vulnerabilities by supplying an application with untrusted input. That input will then be processed by the application in a way that exploits highly sensitive data.
Ok, I feel like I’m losing you. Let’s narrow in on one of the more common types: SQL injections.
A SQL injection allows an end user to execute SQL on a database via forms and fields that take user input (think personal information forms, or comment and review fields), or even API calls. The SQL, if not properly handled and sanitized (i.e. identifying suspect characters and stripping them from a string), can expose sensitive data (passwords, credit card information, personally identifiable information (PII), etc.), render accounts inaccessible via Denial of Service (DoS) attacks, or even take down an entire application.
OK, SO…WHAT CAN I DO ABOUT IT?
A lot, actually!
So now we know SQL injection is some seriously nefarious stuff, but how do we protect our applications against SQL injections?
As a tester, the key is to be proactive and expose vulnerabilities in your test environments before they’re released to production. And you can do that pretty easily.
Let’s get our hands dirty with an example of what this kind of attack looks like.
LET’S TRY IT
First, we need an environment to test on. We can’t just pull up any site and start blasting it with pen tests (that would be bad).
What we’re going to do instead is get an instance of the OWASP Juice Shop application set up for you to start identifying vulnerabilities.
The OWASP Juice Shop is an application whose source is provided free of charge by OWASP for the purpose of penetration testing, and it is a hot security-flawed mess. And it will literally take you 30 seconds to set up and get it up and running.
SET UP YOUR ENVIRONMENT (in 1 minute or less)
Follow the below steps and I will be right here waiting for you once you’re done.
- Sign up to Heroku 100% for free and log in to your account
- Click the button below and follow the instructions
(If you prefer to use node.js, docker, or other forms of deployment, instructions to do so are here.)
And that’s it!
Now that you’ve got your site set up, let’s perform a SQL injection attack.
Step 1. First, we will need open our application. Here, you will either navigate to
localhost:3000 if you have a local node.js instance of the site, or your Heroku site link you defined when deploying the Juice Shop.
Step 2. Now, let’s navigate to the Login page and do a quick sanity check to see if our login fields santize special characters.
Step 3. Now that you’re on the Login page, open your browser’s dev tools and navigate to the Network tab (Press
F12 if you’re on Windows or Linux, or
Command + Option + I if on a Mac).
Step 4. In the email field, let’s type a few characters that could potentially be malicious:
<>'. Type anything you want in the password field and click Log In.
Step 5. We get a failed login attempt. But let’s take a closer look at the request we sent out. In the Network tab, let’s click on the login request.
Scroll down to bring up the Request Payload, and you’ll see something interesting: The email field is NOT being sanitized, which means this field is primed for SQL injection attacks.
Taking it a step further, while the Login request is selected, click on the Response tab and you’ll see some more interesting information. This request is not only showing us that characters aren’t being sanitized, but we are also being given an unobstructed view of what type of SQL database is being used (SQLite), as well as the database schema at hand.
Any savvy hacker would be able to use this information to retrieve an entire list of logins from the Users table, or possibly even clear the table completely, effectively removing all customer information. This act could wreak some serious havoc on a business that relies on user accounts for revenue. But we aren’t going to do either of these things. At least not today.
Step 6. With the information we now have, let’s see if we can do a little injection. In the email field, type the following:
' OR 1=1--
And type any value for the password field. Then click Login.
So what the heck did we just do? If we look at the SQL retrieved from our initial login request, we effectively created a query that returned a true statement.
' closes off the initial query that would take the email value in the
WHERE clause. The
1=1 returns a true statement (since 1 will always equal 1), and the final
-- makes the rest of that query a comment. Therefore the new query we are sending on login is
SELECT * FROM Users WHERE email = '' OR 1=1 --'.
This granted us not just any access, but administrative access to the site. That’s where the real danger begins. Think of ways that unbridled administrative access to your organization’s application could ruin your day. Whatever you’re imagining, I promise you…it gets worse.
For the purposes of our testing, we’re done! We performed our first successful security test via SQL injection. As you can see, it didn’t take much effort, but showed us some pretty big flaws in the application.
As mentioned before, there are various other security issues on the OWASP Juice Shop website (including additional SQL injection vulnerabilities). Feel free to poke around, and leave me a comment below to let me know what you find!
- To read more about OWASP top 10, click here.
- To be a cheaty cheater and gain access to all OWASP Juice Shop vulnerabilities, click here.