Taint analysis is one of the key processes in application security as it deals with the security implications of different processes and inputs while coding. It is focused chiefly on the user’s input flow in the system and how it can disrupt or corrupt the system design.
Programmers use this analysis to reduce the possibility of any risks involved with application development. One such risk is the SQL injection which usually results when the other parts of a program receive user input without the proper security measures. Coding is a very detail-centric process; any wrong input can disrupt the entire code. Moreover, it can maliciously alter the program, resulting in flawed output. Taint analysis is essential for program security on multiple levels, such as the attack surface.
Taint Analysis
Let us see taint analysis in a more linguistic light to understand it better. Taint means “a trace of a bad or undesirable substance or quality,” and when you carry this meaning over to the programming context, taint analysis means analyzing and mitigating any issues this taint may cause in your program. If there is an unverified distribution of data across the program while it is in the operational phase, it can lead to a plethora of problems.
This analysis is specifically designed to remove the “taints” before they can affect the program in any way. Attackers always look for vulnerabilities in system operations to obtain confidential information that can be used later for various cybercrimes, such as blackmail. Moreover, if they manage to land the attack successfully, they can conduct operations that are very detrimental to the program. Let us look at various aspects of taint analysis to understand how it can help secure your application programming.
Taint Sources
Taint analysis is centered on tainted data, which the attacker uses to conduct unauthorized operations that disrupt the program. This tainted data is the attacker’s cue to launch malicious operations within the program. Locating and resolving them can be tricky if they get ingrained within the code. However, if they are spotted at an early operational stage, it can be simpler to get rid of them. One such instance where the application can be vulnerable to risks like SQL injection is when external and unprotected data is used to incorporate database queries into the programming.
You now have an idea of tainted data, but what are taint sources? These are the locations where the application gets access to this unwanted tainted data. These locations make the application susceptible to welcoming corrupt input that ultimately dismantles the entire code. As a programmer, one must be extremely vigilant of taint sources and get rid of them without a second thought. Here is an example of a taint source operating as an HTTP request parameter.
void ProcessRequest(HttpRequest request)
{
....
string name = request.Form["name"]; // taint source
// now "name" contains potentially tainted data
....
}
Tainted Data Transmission
Tainted data can take many routes in any application, making it tricky to cover all the possibilities. It goes without saying that determining these routes is a vital step of taint analysis. The tainted data can be transmitted from a taint source to different variables, which alters the rest of the statements in the code, resulting in a flawed output. This data can then act as the arguments of various functions, replacing their originally intended arguments. For instance,
void ProcessRequest(HttpRequest request)
{
string name = request.Form["name"]; // taint source
// now "name" contains potentially tainted data
string sql = $"SELECT * FROM Users WHERE name='{name}'";
ExecuteReaderCommand(sql); // tainted data passed as an argument
....
}
void ExecuteReaderCommand(string sql)
{
// sql contains potentially tainted data here
....
}
Taint Sinks
Every coding program or operation has key points which are highly protected. Once the tainted data gets to this point, your application or program will suffer the worst possible consequences; invalid output or instant code deletion. The sinks can vary depending on the potential vulnerabilities. These vulnerabilities are bugs or errors in the program code that can make it susceptible to attacks. These bugs remain hidden in the program; it is mostly too late before you find out.
Zero-Day Vulnerability
One type of potential vulnerability is the “zero-day vulnerability.” It is completely unknown to the programmer, and hackers use it to steal and alter valuable data. This usually occurs when the hacker can release the malware into the program before a patch has been implemented to protect it. Here is an example of what the code will look like when the taint sink is the transfer point of a query string to the SQL command object.
void ProcessRequest(HttpRequest request)
{
string name = request.Form["name"]; // <= taint source
// now "name" contains potentially tainted data
string sql = $"SELECT * FROM Users WHERE name='{name}'";
ExecuteReaderCommand(sql); // tainted data passed as an argument
....
}
void ExecuteReaderCommand(string sql)
{
using (var command = new SqlCommand(sql, _connection)) // <= sink
{
using (var reader = command.ExecuteReader()) { /*....*/ }
}
....
}
As you can see, the external data is directly forming an SQL query which the programmer did not initially intend. Taint analysis is a static analysis, but it is considered more of a set of diagnostic rules.
Removing Vulnerabilities
Removing a potential vulnerability is of utmost importance when you come across a potential vulnerability. To eliminate such a threat, the best practice is to verify the external data or convert it into a secure form before allowing it in. However, these fixes can vary depending on the type of attack. In the case of the SQL injection we have seen above, parameterized queries can be the answer:
String userName = Request.Form["userName"];
String query = "SELECT * FROM Users WHERE UserName = @userName";
using (var command = new SqlCommand(query, _connection))
{
var userNameParam = new SqlParameter("@userName", userName);
command.Parameters.Add(userNameParam);
using (var reader = command.ExecuteReader())
....
}
After eliminating the corrupt script, its code will appear on the web page as plain text. Hence, the danger is averted, and your program or application is safe.
Conclusion
Static taint analysis deals with security implications of different coding inputs and processes. By focusing on the user’s input flow, it evaluates how that flow can corrupt the system design. It’s a very important process because it reduces the possibility of risks in application development. That’s why we provided here the definitions and explanations of taint analysis and its components, including taint sources, data transmission, and sinks.