Basics of Code Review
In today's fast-paced world, everything is done over the internet. You will be amazed to know that 3.48 million apps are currently available on the Google Play Store, and 3,739 new apps are added daily. Developing an application begins with programming. However, the security aspect is often neglected or compromised during the process. Imagine the chaos it will cause if these products contain serious vulnerabilities. Hence each product needs to be checked with every possible security angle before it hits the market!
What is Source Code Review?
A secure code review is a line-by-line analysis of the source code of an application, usually performed to find any security risks overlooked during the pre or post-development phase. A secure code review aims to analyze an application's source code and determine whether it has any security vulnerabilities or flaws.
A code review considers security, performance, functional level issues, etc. Today, many organizations are implementing this as part of the compliance or regulatory process and the SDLC process.
The focus of a Secure Code Review
Eight security categories or areas are usually examined in a secure code review. A weak application makes itself a target for attackers and is more likely to be used in an attack if it is weak in any area. Here are some areas to look for:
- Authentication
- Authorization
- Session management
- Data validation
- Error handling
- Logging
- Encryption
- Input sanitization
Each of the mechanisms mentioned above is susceptible to several security risks. Risks in the handling of passwords often affect authentication. Flaws related to the type of information in a message often affect error handling. Flaws in regular expressions often affect data validation.
Source code reviews look for specific flaws listed in the Common Weakness Enumeration. "It serves as a common language for describing software security weaknesses, as a measure for software security tools addressing these vulnerabilities, and as a baseline standard for identifying, mitigating, and preventing weaknesses."
Code Review Methodology
Code reviews can be performed in several ways. Here are a few methods you can try:
Checking for bugs by string matching/grepping
The fastest way to find low-hanging fruit is to look for patterns of known vulnerabilities. When searching for PHP system functions, use the following command on a Linux machine.
$ grep -R 'system\(\$_' *
The above command uses the grep to find the system-related functions carried out in the source code.
- Source code security (and quality) aren't covered/assured much.
- Based on your list of patterns, you know there are no problems.
- You must understand all the dangerous functions and patterns.
- In the end, you end up using very complex regular expressions.
This approach works well when you don't have enough time for timesboxed reviews. As part of a more extended review, it can also help you familiarise yourself with the code base. However, it may not be the best way to conduct proper reviews.
User input Validation:
You can also review the application's source code by following all the user-controlled inputs and finding all the routes/URIs available to access the application. Start by finding out how data is provided to the application (example in ):
$_POST / $_GET / $_REQUEST
$_COOKIE / $_SERVER
The coverage provided by this method is good. You will, however, need a good understanding of the framework and language for this approach. Additionally, if the same function is called repeatedly, you may have to review it frequently.
Reading The Source Code
Alternatively, you can read the source code of the application. Instead of looking for vulnerabilities, try finding what controls are missing in the code. In this way, you can determine if any security control is not in place and might become vulnerable on their own.
This method is the most labor-intensive but provides excellent coverage compared to other methods. The importance of keeping good notes when using this method cannot be overstated.
Each application functionality should be checked separately, such as
- Password reset.
- Access to a database.
- The authentication process.
This functionality's code should also be reviewed. Since each application has a different behavior, this works particularly well across multiple applications.
As a result, you'll receive excellent coverage for the functionality reviewed and learn what mistakes people usually make when using that functionality. Your scope, however, is limited to what you reviewed.
Common Examples of Vulnerabilities
It isn't easy to perform a source code review through each line. Regex can automate searching for common things such as SQL &XSS entry points and hardcoded secrets such as passwords or an API Key.
The following list shows how to use the grep command to automate searches for common vulnerabilities such as SQL Injection, XSS, session management, etc., using regular expressions.
SQL Injection
SQL Injection occurs when variables are concatenated and the input is not sanitized properly.
Quick brainstorming
- Developers might miss out on variables that don't pass through filters.
- During code review, look at the input filters. Extract all variables from the concatenated query and see if any variables are not passed through the filters. These variables might be vulnerable to SQL Injection.
In the above snippet, the password variable is vulnerable to SQL injection. Since only the name parameter is sanitized here.
SQL Injection in Stored procedures
Stored procedures though a remedy for SQL Injection, can be vulnerable if the variables are concatenated within the SQL Query:
In the above snippet, the username variable that is declared is concatenated.
Look for procedures for concatenating variables and verify whether the variable takes any user input. Stored procedures are vulnerable to SQL injection when:
- Concatenated SQL queries are used
- exec, execute, or sp_executesql is called to execute the query
Executing a dynamic query in a stored procedure
Using exec()
Using sp_executesql()
sp_executesql can be used to execute dynamic SQL query. Here, the user input is not parameterized before sending the @sql query to sp_executesql
Additional Protection – Blacklist Filters
For each page request, the input parameters are compared against a black-list filter; we can look for the blacklist filters in the code.
Sample Blacklist:
Cross-Site Scripting (XSS)
XSS is possible when:
- User input is reflected as it is to the browser (Reflected XSS)
- Applications do not validate user input and store it.
Reflected XSS
User input from request parameters is displayed to the browser without proper encoding.
Code Review Strategy:
- Extract all variables that form part of the response sent to the browser. Here, we are interested in variables that are not HTML encoded.
- Examine whether values assigned to these variables come from any user input/request parameter.
We can look for the vulnerable code by using the below regex. Check if HTML Encoding is applied on extracted variables
- <%\s*=\s*(.*)\s*%>
- Response\.write\s*\(?\s*(.*)\s*\)?
- out\.println\s*\(?\s*(.*)\s*\)?
After extracting the variables, the response should look something as below after running the regex.
ASP.NET |
Java |
<%=name%> response.write name asp:Label ID="Label1" |
<%=name%> out.println(name); |
Once all variables in response are extracted:
- Check if the values assigned are from user input or request parameter
- For each extracted variable, see if the assignment has any of the following patterns:
- Request.QueryString
- Request.Form
- Request.GetParameter
- <control_name>.text
- <control_name>.value
If similar patterns are found, you can look for input sanitization at that part of the code
Persistent XSS
In the case of persistent XSS, the user input is stored in the database and retrieved as query results based on the functionality.
Code Review Strategy:
- Look out for all SQL insert statements that take user inputs as values.
- Extract out the table and column names from the insert statements.
- For each column and table name in this structure:
- Check if they form part of SELECT query elsewhere in the code base(if the application is fetching that data)
- Check if the result set is displayed back to the browser
- Check if they are properly sanitized or not.
.NET Protection – Anti-XSS filter
Sensitive data in Log Files
Developers may inadvertently write sensitive data to log files or to the console for debugging.
Code Review Strategy:
- Find all calls and statements that send data to log file or console
- Check the data that is being passed to those logging functions
- Does it include any sensitive data like passwords, API Keys?
JAVA org.apache.log4j.Logger log.info(“passwd" + passwd + "logs in"); |
ASP.NET log4net.ILog Log = LogManager.GetLogger(); log.warn(), log.debug(), log.error(), log.fatal() myLog = new EventLog(); myLog.WriteEntry(sessid, EventLogEntryType.Error) |
Using grep, we can look for sensitive data, such as passwords and API Keys.
We can look for sensitive data written to the console; Developers might also send messages to the System console for debugging. We can check that by using the below grep sample examples
Look for DDL statements.
Data definition language (DDL) statements let you create and modify BigQuery resources using Google Standard SQL query syntax.
We can look for the statements using the below sample grep examples.
For the above grep command, we might see something as of below.
Look for functions that execute system commands
We can look for system commands using the below sample grep examples
For the above grep command, we might see something as of below.
ASP.NET System.Diagnostics.* Process.Start(cmd.exe) |
Java .java.lang.runtime Runtime.getRuntime.exec |
ASP set wshell = CreateObject("WScript.Shell") wshell.run "cmd.exe" |
Automated Code Scanners
Non-Commercial tools
Commercial Source Code Scanners
Code Review Mind map
When it comes to code review, Mind Maps are always useful. They help you in keeping all steps and methodologies in one document. And it can be used to follow methodologies without forgetting steps. You can follow this specifically created mindmap.
Source: https://mm.tt/map/2397834673
Conclusion
We have covered quite a set of examples of vulnerable code snippets and grep commands that might help us to find similar kinds of vulnerabilities. We hope the methodology will be helpful to you whenever you happen to be able to do code audits.
Read more about this security service to learn about code review goals and more.
References:
- https://web.mit.edu/6.005/www/fa15/classes/04-code-review/
- https://www.scnsoft.com/blog/web-applications-security-source-code-review-vs-penetration-testing
- https://snyk.io/blog/secure-code-review/
- https://blog.entersoftsecurity.com/source-code-review/
- https://pentesterlab.com/exercises/codereview/course
- https://vickieli.dev/hacking/code-review-101/
- https://www.niiconsulting.com/services/security-assessment/source-code-review.php
- https://deepsource.io/blog/java-code-review-guidelines/
- https://owasp.org/SecureCodingDojo/codereview101/