Performing a source code review is one of the best ways to find security issues in an application. But how do you do it? In this guide, we’ll go through the basics of code analysis and some tips for performing a security code review on your application.
Before you start reviewing code, learn what the most common vulnerabilities are for the target application type. Getting familiar with the indicators and signatures of those vulnerabilities will help you identify similar patterns in source code. For example, the signature for an XXE vulnerability is passing user-supplied XML to a parser without disabling DTDs or external entities. (More about XXEs here.)
Although vulnerabilities have common patterns in code, these patterns can look quite different in different contexts. Knowing the programming language, frameworks, and libraries you are working with will help you spot vulnerable patterns more accurately.
Before we go on, there are a few concepts that you should understand: “sources”, “sinks”, and “data flow”. In code analysis speak, a “source” is the code that allows a vulnerability to happen. Whereas a “sink” is where the vulnerability actually happens.
Take command injection vulnerabilities, for example. A “source” in this case could be a function that takes in user input. Whereas the “sink” would be functions that execute system commands. If the untrusted user input can get from “source” to “sink” without proper sanitization or validation, there is a command injection vulnerability. Many common vulnerabilities can be identified by tracking this “data flow” from appropriate sources to corresponding sinks.
If you are short on time, focusing on a few issues can help you discover the most common and severe issues.
Start by searching for strings, keywords, and code patterns known to be indicators for vulnerabilities or misconfiguration. For example, hardcoded credentials such as API keys, encryption keys, and database passwords can be discovered by grepping for keywords such as “key”, “secret”, “password”, or a regex search for hex or base64 strings. Don’t forget to search in your git history for these strings as well.
Unchecked use of dangerous functions and outdated dependencies are also a huge source of bugs. Grep for dangerous functions and see if they are reachable by user-controlled data. For example, you can search for strings like and “system()” and “eval()” for potential command injections. Search through your dependencies to see if any of them are outdated.
You can complement the above strategy with a more extensive source code review if you have time.
Focus on areas of code that deal with user input. User input locations such as HTTP request parameters, HTTP headers, HTTP request paths, database entries, file reads, and file uploads provide the entry points for attackers to exploit the application’s vulnerabilities. Tracing data flow from these functions to corresponding sinks can help you find common vulnerabilities such as stored-XSS, SQL injections, shell uploads, and XXEs.
Then, review code that performs critical functionalities in the application. This includes code that deals with authorization, authentication, and other logic critical to business functions. Look at the protection mechanisms implemented and see if you can bypass them. At the same time, check how business and user data are being transported. Is sensitive information transported and stored safely?
Finally, look out for configuration issues specific to your application. Make sure that your application is using secure settings according to best practices.
As you can see, manual code review can be quite tedious and time-consuming. Using SAST (Static Analysis Security Testing) tools is a great way to speed up the process. Good SAST tools identify vulnerable patterns for you so that you can focus on analyzing the impact and exploitability of the vulnerability.
Now, let’s search for a vulnerability using ShiftLeft’s SAST tool, NG SAST! We will be analyzing the source code of an example application, shiftleft-java-demo. Register for a free NG SAST account here. After you register, you will be taken to a dashboard.
From there, go to “Add App” on the top right, and select “Public and Private repos”.
After you authorize Shiftleft to access your Github repositories, and click on “Click to see a list of your repositories”, you should see a list of your repos available for analysis. If you choose to analyse one of your Github repos, all you have to do is click on it and ShiftLeft will automatically import it for analysis.
For now, we will be using a built-in demo app. So go to “Java > Demo”, and click on “Next”.
You should now see a new application on your dashboard! ShiftLeft is working hard to find vulnerabilities in the application.
Let’s dive into the findings! Click on the shiftleft-java-demo project, and you should see findings sorted by vulnerability type on the bottom left. Click on “Sensitive Data Leak”. This takes you to all the sensitive data leaks NG SAST found.
Sensitive data leaks happen when an application exposes sensitive data, such as credentials, secret keys, personal information, or configuration information to people that shouldn’t have access to that information. For instance, if an application writes sensitive personal information like customers’ credit card numbers into application logs, that information becomes accessible to system analysts who can read logs.
The “source” of a sensitive data leak is usually a variable that contains sensitive information. And a “sink ” in this context could be any function that causes information to be displayed to users, such as logging, automated emails, and writing to web pages. If the sensitive “source” can make its way to a “sink” function, the sensitive data could be leaked.
Let’s dive into one of these sensitive data leaks and figure out why it happened! Click on one of the sensitive data leaks found. Here, I will be looking at Sensitive Data Leak #92, Sensitive data is leaked via routingNumber to log in Account.<init>.
The NG SAST tool tracks how data flows through applications to find patterns that indicate vulnerabilities. This window shows you where the vulnerability is located and how it happened, starting from the source, to the sink.
You can see that source is a variable named routingNumber on line 31 in a file called Account.java. And the sink is in a file named Logger.java.
Click on the link in the first step to go to that line in code. You should see a class declaration that declares a new class named Account. The class has five properties: accountNumber, routingNumber, type, initialBalance, and initialInterest. From the class name and its contents, we can guess that this class is used to represent a bank account.
NG SAST tells us that the routingNumber is being leaked to logs via CustomerController.java. Let’s head over to CustomerController.java to see what’s going on there! You can click on the data flow step in your portal and you will be taken to that line in code.
In CustomerController.java, you find code that fetches a customer based on their ID. During this process, the application writes the account information without any redaction or sanitization into logs. This means that anyone who has access to the application’s logs will also be able to access the bank account details of that user!
Congratulations! You just found and analyzed your first sensitive data leak using NG SAST!
Static analysis is the most efficient way of uncovering most vulnerabilities in your applications. If you’re interested in learning more about ShiftLeft’s static analysis tool NG SAST, visit us here. And if you are interested in learning more about common vulnerabilities in web applications, check out our free course on the OWASP top ten.