Security is one of the most important cross cutting concerns for any enterprise grade application. Badly written software with security vulnerabilities can cause millions of dollars of damage not just to the business but to brand reputation as well.
Programmers and developers should understand the importance of writing secure code in order to avoid the most common pitfalls which can result while writing code.
In this article, we will look at three most common types of Security Vulnerabilities that affect code.
SQL Injections
SQL Injection is the most common type of security vulnerability which can occur when writing code that interacts with databases.
To look at an example of SQL Injection, consider the code example below:
The above code example shows querying a customer table to find a customer record with a matching username and password. The problem lies in this line of code:
There are a couple of problems with the above lines of code.
- There is no input validation. The username and passwords parameter are being read without being sanitized and are directly passed to the db query
- The above issue results in sql injection vulnerability
This is because if the user passes ‘ or ‘1’=’1 as the password, this will result in the following SQL query to the database:
If we run this query in the database, this will result in the customer record being fetched irrespective of whether the password provided matches with the stored password or not.
To fix this issue, we should use PreparedStatement to prevent SQL injections, as follows:
In the above example, we are using positional parameters represented using question marks to represent our parameters.
The JDBC API takes care of sanitizing the input in this case and prevents the SQL injection.
Cross Site Scripting
Cross Site Scripting (XSS) is another most common vulnerability which happens in web applications when the web application trusts the user input without validation.
As a result of it, a vulnerable web application could execute the malicious javascript code on the user’s web browser resulting in unauthenticated data to be exposed etc.
To understand this vulnerability, let us see the very simple Java Servlet Pages (JSP) code below:
Here, we are fetching the customer Id from the request parameter from the user and displaying it on the web browser. This request will run fine if customer ID is actually an integer or an alphanumeric value.
However, a malicious user could insert a malicious javascript code; for example, the following code, which will echo the user’s cookie.
This might look harmless as the code is still running on the attacker’s browser computer. However, the real damage occurs when such malicious code gets embedded within the web application such as in blog post comment and then gets executed on other user’s browser.
The attacker can then choose to transmit such sensitive data onto a remote computer or trick the user into visiting malicious websites.
Preventing XSS Attacks
The simplest way to prevent XSS attack is to encode the data which is to be displayed onto the browser. For example, for above case we would display the data as follows:
The browser will HTML encode the data which instead of running the malicious code as is on the user’s computer.
Insecure Sensitive Data Storage
Insecurely storing the sensitive data such as passwords is another most common vulnerability which the developers mistake while storing. For example, using a hashing technique is the common technique for storing the sensitive data such as passwords.
However, this is not enough. Let me illustrate the following username/password table below in the database.
username | password |
user1 | 0a25efb0-07d3-4210-9e27-1f00c844887c |
user2 | 8b563bb1-1ff2-49ff-827e-aea706593c93 |
user3 | 0a25efb0-07d3-4210-9e27-1f00c844887c |
In the above example, password is the encrypted field which seems fine. However, there is a problem that if an attacker gets access to the database and cracks the password using a brute force or a dictionary attack for user1. They automatically get the password for user3.
This is because the hash value of user1 and user3 is the same (perhaps because their passwords were the same).
The right way to store passwords or any sensitive data for that matter is to add salts.
A salt is a fixed length random value added to the hash function while generating the hash value for the user’s password. This results in the different hash value being generated even if the passwords were the same.
Since the salt value is different for each user, the salt needs to be stored against each user’s row as follows:
username | password | salt |
user1 | 0a25efb0-07d3-4210-9e27-1f00c844887c | 2ceeaa01-2d30-46a6-ae39-378e511b0aa3 |
user2 | 8b563bb1-1ff2-49ff-827e-aea706593c93 | 79bb1a87-628f-48d2-84c1-7dcb8e60e5dc |
user3 | 75e4ced0-c84f-4fa3-9ff6-d2175524c648 | d1121e1b-99e6-4905-b349-8ba891053a4d |
Conclusion
In this article, we looked upon the most common types of security vulnerabilities: SQL Injection, Cross Site Scripting and Insecure Sensitive Data Storage that affect code and how to fix them.