The aim of this article is to be a resource on command injection and its impact on the modern web. We will be discussing what command injection is and explore some examples on Kotlin. Finally, we will address how you can mitigate this vulnerability with our sample project.
For this purpose, we'll build a sample project with Spring Boot and Kotlin as our stack of choice. If you don't have any experience working with either of these, don't worry. You should be able to grasp the main concepts beyond the peculiarities of the tech stack.
Nevertheless, we recommend that you take some time to familiarize yourself with the language and explore the Spring tutorial, which we'll be using as our basis for our sample project.
Before the Jump
Before we take on command injection, let's make sure you have your environment set up. Start by first crafting a demo site in Spring boot using the start.spring.io tool.
Note: We will assume that your environment is ready to work with Java and that you have an IDE to code. If that is the case and you want to go straight to the main subject, feel free to skip this section.
Now please proceed to https://start.spring.io and set up our project. Don't forget to select Spring Web as your dependency, Gradle as your manager, and Kotlin as your language of choice.
After the download, proceed to the src/main/kotlin/com/example/demo folder and create a class file called HomeController.kt. There you can input the following code:
package com.example.blog
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.ui.set
import org.springframework.web.bind.annotation.GetMapping
@Controller class HomeController {
@GetMapping("/")
fun home(model: Model): String {
model["title"] = "Blog"
return "home"
}
}
Then proceed to the src/main/resources/templates folder and corresponding header and footer templates. Notice that we have chosen the mustache template syntax; however, you can make them in the syntax of your preference.
header.mustache
<html>
<head>
<title>{{title}}</title>
</head>
<body>
footer.mustache
</body>
</html>
home.mustache
{{> header}}
<h1>{{title}}</h1>
<p>This is a test blog.</p>
{{> footer}}
And that's all you need for now.
You can proceed to run your code by typing "gradle bootRun" in the terminal and seeing your website on localhost:8080.
Blog home page.
If you want to understand better what is happening under the hood before progressing into the article, please go to the Spring Boot tutorial page.
Explaining Command Injection
To explain what command injection is, we need to talk about injection in web applications.
You might have heard SQL injection being talked about between developers and in some circles around the web. In a nutshell, injection is a type of attack where an attacker attempts to hijack the user input. By using specific characters or strings of characters, the attacker can bypass the application and manipulate or gain access to an application's database.
This attack, and the vulnerability related to it, became a buzzword for web security in the early 2000s as it became notorious for its seemingly simple and yet devastating potential.
Now, command injection, or code injection, is a special injection attack where the attacker injects JavaScript or Java code into the server to seize control over it. Subsequently, the browser or application runtime wrongly interprets this malicious code as valid since it can't distinguish between the code the developer intended and the attacker's code.
This situation is particularly hazardous considering that any arbitrary code from an attacker that the application executes can bypass any security measures, potentially even surrendering the server altogether.
Thankfully, code that takes strings as parameters and executes commands on the system is not standard on most development projects. For the most part, best practices discourage developers from using functions like exec or directory.execute unless absolutely necessary.
Nevertheless, it's essential to be aware that some of the libraries you use in your project might include these functions and put your platform at risk.
Examples of Command Injection
Now that you know what command injection is and how it can reach your operating system, let's look at an example.
curl http://localhost:3000/index?image=prof.png;nc%20-l%205656%20|/bin/bash
In this sample request, you can see that the attacker is attempting to run the following command:
nc -l 5656 | /bin/bash
This command, called "netcat," can run arbitrary code on our server on behalf of the attacker and cripple it entirely.
We are assuming that your application is using one of the vulnerable functions mentioned above. In this case, it is feasible to consider that an attacker has an avenue to reach your server command line by simply appending commands to a request.
@Controller class HomeController {
@GetMapping("/index")
fun home(model: Model, image: String): String {
model["title"] = "Blog"
// Exec sample
val result: String = exec("git log --oneline " + image, stdIn = "yes")
model["image"] = result
return "home"
}
}
Command Injection Vulnerabilities
To mitigate this vulnerability, we need to make sure that we are not using functions that can execute commands unless they're absolutely necessary. After all, if there is no point of access, there is no risk. Thus, our first line of defense—prevention—is incredibly effective against this kind of threat.
Additionally, be sure to apply an input sanitization mechanism for any user input provided. As a general rule of thumb, restrict and regulate all paths of user input that your application offers. For example, look for ways to change dynamic input into fixed selections and use safelists to validate all input.
Lastly, use security analysis tools like StackHawk and routinely scan your application for vulnerabilities. StackHawk can test your applications, services, and APIs for security vulnerabilities and threats. It can also inform your team so they can effectively address them.
Conclusion
In the process of creating engaging and feature-rich solutions for the web, it's easy for developers focused on deadlines and milestones to disregard security. Security and robustness are aspects treated as an afterthought for projects focused on producing results fast at the lowest cost possible. Unfortunately, that is the reality that the market has embraced as an acceptable tradeoff for the potential of explosive growth.
However, it is crucial for the developers building today's web to push back against these trends. Likewise, engineers responsible for building the infrastructure and tools of the future must be aware of these decisions' impact.
Sometimes the correct implementation of fixes, patches, and mitigation strategies can be incredibly complex. That's particularly true if your platform is quite large.
That's why solutions like StackHawk are an excellent asset for those looking for a robust and straightforward way to address security problems.
StackHawk is a proven test suite that accommodates developers and managers with a wide variety of testing tools. Our sophisticated algorithms and comprehensive platform provide a centralized command center to monitor and guarantee your platform security. This helps you and your business be ready for the challenges of the modern web.
Be it command injection, scripting, or any other vulnerabilities, StackHawk provides outstanding value for your teams and partners.
Check it out here.
This post was written by Juan Reyes. Juan is an engineer by profession and a dreamer by heart who crossed the seas to reach Japan following the promise of opportunity and challenge. While trying to find himself and build a meaningful life in the east, Juan borrows wisdom from his experiences as an entrepreneur, artist, hustler, father figure, husband, and friend to start writing about passion, meaning, self-development, leadership, relationships, and mental health. His many years of struggle and self-discovery have inspired him and drive to embark on a journey for wisdom.