Secure Code Reviews- What, Why and How? (Part-01)

Main Banner

Secure Code Reviews are one of the most crucial part of any organization’s security posture as they play a key role in protecting businesses from data breaches and cyber-attacks. This post is about the introduction to SCR and exploring different approaches for finding vulnerabilities in applications. I am starting this series because it’s something I wish I had when I started doing SCRs. So, let’s kick things off by gathering the basics.

Table of Contents

  1. History of Code Reviews
  2. Comparison with Traditional Code Reviews
  3. Introduction
  4. Need for SCR
  5. Pre-requisites
    1. Terminologies in SCR
  6. Setting up SCR Environment
    1. Decomposing an application
  7. Automated Testing- SAST & SCA
    1. Static Application Security Testing
    2. Software Composition Analysis
    3. Secrets Scanning
    4. How to choose a tool?
  8. Resources
  9. Conclusion

A brief history about code reviews

history

Concept of code reviews isn’t new, it has been around since 1970s when Michael A. Fagan introduced the Fagan inspection process through his paper titled as “Design and code inspections to reduce errors in program development” at IBM, which is a formalized method aimed at systematically reviewing source code for defects and enhancing overall software reliability. Fagan inspections marked a turning point, emphasizing a structured approach to defect detection and fostering a culture of thorough examination within the SDLC.

Over the years, the significance of code reviews has only grown, evolving beyond formal inspections to include various informal methods like pair programming and automated tools. After development of various source control systems like Git and SCM (Source code management) tools, collaborating on same code base from anywhere on planet became easier. This led to development of digital peer reviews and one such creation was of the earliest form of web-based code review tool called Mondrian by Guido Van Rossum at Google. Detailed talk on this can be found here.

Code Review VS Secure Code Review

Traditional code reviews and secure code reviews serve distinct purposes within the software development process, with a focus on different aspects of code quality and project goals.

Code reviews primarily aim to improve the overall quality of the codebase by identifying and addressing issues related to readability, maintainability, coding standards adherence, and general software design. These reviews involve peers or team members examining the code to catch bugs, ensure consistency, and share knowledge among team members. The emphasis is on enhancing the efficiency of the code, promoting best practices, and fostering collaboration.

Secure code reviews, on the other hand, specifically focus on identifying and mitigating security vulnerabilities within the code. There are various names given for SCR- Secure Code Auditing, Security Code Review or Source Code Review; all are referring to the same practice. The goal is to ensure that the software is resistant to potential security threats and attacks. Secure code reviews involve a detailed examination of the codebase to identify vulnerabilities such as SQL injection, cross-site scripting, and other security weaknesses. It includes an evaluation of the code against security best practices, compliance with security standards, and adherence to secure coding guidelines.

SSDLC

What is a Secure Code Review?

Secure Code Review is a white-box security testing process in software development where the source code of an application is systematically examined for security vulnerabilities and potential issues. In traditional software development settings everyone is obviously familiar with peer code reviews which focus on performance, quality of code and functionality of the application. But secure code reviews play a distinct role by prioritizing security practices; and how the absence of these practices might lead to security risks. In past few years, lot of organizations are implementing a Secure SDLC process to make SCR a regular practice at early stages.

Why do we need Secure Code Reviews?

Quote from OWASP Code Review Guide- “We never get hacked, we don’t need security” shows how businesses are not willing to spend the appropriate amount of time and money on security. There are numerous reasons ranging from limited awareness of risks, cost concerns, time constraints, trust in employees and more which lead to skipping important security checks that are absolutely needed. If code has not been reviewed for security holes, the likelihood that the application has problems is virtually 100%.

Many modern organizations are now following good security practices through conducting VAPT as it is crucial for compliance with various regulations and standards. While Vulnerability Assessment and Penetration Testing (VAPT) techniques, including black-box testing, are valuable for identifying vulnerabilities in a software application, they serve a different purpose than secure code reviews. Secure code reviews are conducted during the development phase, allowing for the early identification of vulnerabilities before the application is even deployed. This helps address issues at their source itself, preventing them from becoming embedded in the final product. Most developers in their early career are not taught secure coding, security in general and how vulnerabilities can be exploited. They tend to make coding mistakes and have very little to no idea about OWASP Top 10, CWE Top 25, PCI-DSS, or HIPPA.

Some of the benefits of performing Secure Code Reviews at early stage in SDLC are:

What knowledge is required?

langs

Performing secure code reviews requires familiarity with various things like Object Oriented Programming languages, how software lifecycle is implemented in a professional environment, in-depth understanding of language-specific nuances, data structures and coding patterns to properly identify security issues.

A reviewer should also be familiar with security fundamentals of Web Application security and should have grasp of principles like common vulnerabilities such as input validation pitfalls, XSS, CSRF, and all other OWASP Top 10.

Understanding network protocols, like TCP & UDP and their implementation during network programming in various languages also helps in identifying issues with secure communications in code. The reviewer should also be familiar with security standards such as:

  1. CERT Secure Coding Standards,
  2. MISRA C/C++,
  3. OWASP Secure Coding Practices Project
  4. AUTOSAR C++14
  5. Java-EE-Frameworks JSF, GWT and Spring MVC/Security

codestandards

Reviewer should also possess detailed understanding of authentication mechanism e.g., OAuth, OpenID. This would help in identifying implementation of access controls, session management, and user authentication issues. It is also a plus point if the reviewer has fundamental knowledge of Threat modeling and how to anticipate potential attack vectors, attack surfaces and entry points for understanding context.

There are various SCR Checklists available for checking vulnerabilities while performing a secure code review such as this one; but reviewer can also create his own checklist based on existing ones which should cover categories of vulnerabilities and questions he/she needs to ask for understanding the code. For example; let’s take Authorization category- reviewer should ask “Is the placement of authentication and authorization check correct?, Is password complexity check enforced? Does application support password expiration?” and so on. This would help reviewer to understand the code more clearly while code crawling.

Reviewer should also be familiar with looking at weaknesses in Business Processes such as Deployment, Application Model, Boundary Checks, various business logic bugs and Business Rules. Understanding consequences of system failing, enterprise being affected in any way if the application is not behaving and performing as intended can also be a plus point.

Terminologies in SCR

There are some jargons thrown around in a SCR review which all security reviewers should be familiar with. Some of them are as following:

  1. Source- In secure code review, a “source” refers to a user-controllable input or external data that enters the system. Sources can include user inputs through forms, data from external APIs, or any other input that originates from an untrusted external entity. Understanding and properly handling sources is crucial to prevent security vulnerabilities like injection attacks (e.g., SQL injection, command injection) where malicious data is injected into the application.

  2. Sink- A “sink” is a point in the code where data from a source is used in a way that could lead to a security vulnerability if not handled properly. Common sinks include database queries, file operations, and command executions. Sink points are vulnerable to attacks when untrusted data flows into them without proper validation, sanitization, or parameterization. Identifying and securing sinks is a key aspect of secure code review to prevent security issues like injection attacks.

Let’s try to understand it more clearly through an example. Consider a web application that takes user input to construct an SQL query for authentication:

username = getRequestParameter("username")
password = getRequestParameter("password")

query = "SELECT * FROM users WHERE username='" + username + "' AND password='" + password + "';"
executeQuery(query)

In this example, the username and password variables are potential sources. If an attacker enters malicious input, such as ‘ OR ‘1’=’1’ –, as the username, it can manipulate the SQL query to always return true, bypassing authentication.

Continuing from the previous example, the executeQuery function serves as a potential sink:

def executeQuery(query):  # Sink
    # Code to execute the SQL query
  1. Data Flow Path- The data flow path represents the sequence of operations that the data undergoes as it moves through the codebase. In the context of secure code review, understanding the data flow path is crucial for identifying how user-controllable inputs (sources) are processed and eventually reach points in the code where they are used (sinks).

  2. Control Flow- The data flow path is influenced by the control flow of the application. Conditional statements, loops, and branching logic can impact how data is processed and which code paths are executed.

  3. Taint- “Taint” refers to the tagging of data as potentially untrusted or insecure. When data is tainted, it means that the origin of the data is not completely trusted, such as user inputs or external data sources. Taint tracking involves marking certain data as tainted and then tracing its flow through the program.

TaintAnalysis

During taint analysis, the tool marks certain data as tainted at its source, often where it enters the system (e.g., user input). The analysis then traces how this tainted data propagates through the program, identifying every point where tainted and untainted data interact. This process helps uncover security risks such as SQL injection, cross-site scripting, and other injection attacks, where unvalidated user input may lead to unintended consequences.

  1. Linters & Linting- Linters are tools that analyze source code to identify programming errors, bugs, stylistic issues, and potential vulnerabilities. They enforce coding standards and best practices, helping developers write cleaner and more maintainable code. Linters can be language-specific, offering guidelines and suggestions tailored to the syntax and conventions of a particular programming language.

  2. Lexical Analysis- Lexical analysis, often referred to as scanning or tokenization, is the first phase of the compilation process in the context of programming languages. It involves breaking the source code into a sequence of lexical units called tokens. These tokens represent the fundamental building blocks of the code and include identifiers, keywords, operators, literals, and punctuation symbols.

For example:

int main() {
    printf("Hello, World!");
    return 0;
}

The lexical analysis may produce the following token stream:

How to setup a SCR environment and start a review?

Before setting up a review environment, reviewers should convey strategy to be followed during the whole process. Secure Code Reviews are always a combination of Human-involved Manual Review and Automated testing with SAST Tools. It should already be clear during initial meetings on what strategy needs to be followed- reviewer should check if development teams have already conducted formal inspections, over-the-shoulder reviews, ad hoc reviews, any tool-assisted reviews or pair programming. Getting hands-on developer’s documentations is also beneficial for understanding the codebase. In my opinion, each organization has their own needs so reviewer should create their own process considering the factors such as risk, in-scope fields, context, LOC (lines of codes), deadlines, tools at hand, and team size. Analyzing these things would help to give clear strategy and ease the process.

Once the strategy is decided, after the code hand-off from development team to security team; reviewers should create a availability list of tools based on the languages and frameworks in codebase. First step is always performing a LOC analysis of the entire code and then try to identify dependencies. One of the good tool for conducting LOC is cloc- which counts all physical lines of source code in many programming languages and is well maintained.

Then comes the installation of tools based on languages present in code. If the code is Java based then, installing SonarQube, FindBugs, FindSecBugs, Fortify, Insider CLI, reshift and PMD would be great start. The choice of tools can vary from language to language- most of the SAST Tools now have multi-language support too. Security team also needs to consider choosing vendors of SCA- Source Code Analysis or SAST based on the factors such as is it Paid or Open Source/ Free, what licenses are required, detection capabilities based on OWASP Top Ten or other standards, accuracy with False Positive/ Negative rates, setup-complexity, support from the vendors and if it has sufficient documentation.

One more thing that could help in smooth review process is choice of IDE for manual review; this should be decided by consulting with development team as to understand on what IDE was the code written and run. Replicating that particular environment with IDE, plugins installed, debuggers used, SCM setup, can help explain a lot of things about the code. It is a good practice to mirror development environment.

codecrawling

So, other important skill that reviewers can inculcate is of code crawling. Code crawling refers to the systematic and detailed examination of source code to identify vulnerabilities, security issues, and adherence to coding standards. During code crawling, a reviewer manually inspects the codebase to understand its structure, dependencies, and potential security risks. This process involves analyzing individual lines of code, reviewing functions and modules, and assessing how different components interact with each other.

Decomposing an application

Once the environment is set up, the next step is to decompose the application into smaller components. This is done to understand the dependencies between components. Reviewer can then crawl the code in order to review target and interface entry points, looking for key code pointers, wherein possible vulnerabilities might reside.

Key points to follow while performing SCR:

whiteboard-TM

Observing above diagram, we can see a simple threat model on a whiteboard and relevant data flows, trust boundaries and existing security controls (authentication, authorization, encryption), with the general focus on the processing and storage of sensitive data and access to it. When source code analysis is performed outside of Secure SDLC, such as on existing applications, instead of reviewing all source code with equal focus, a reviewer can prioritize the security code review of components whose threat modeling has ranked high risk threats.

Automated Testing- SAST & SCA

Automated testing plays a crucial role in complementing manual Secure Code Review (SCR) for several reasons. While manual code reviews are essential for in-depth analysis, human reviewers may overlook certain issues, and the process can be time-consuming. Having your code tested automatically for common security problem is an important aspect for ensuring secure applications – not only but especially for agile development and DevOps. A number of enterprise solutions and tool categories such as SAST, DAST and IAST are available, all with different features and suitability for specific environments.

Static Application Security Testing (SAST)/ Static Code Analysis-

SAST analyzes the application’s source code, configuration files, and other artifacts without executing the program. It also helps in examining the code structure, data flow, control flow, and dependencies to identify potential security vulnerabilities. It is a proactive approach to identifying security issues early in the Software Development Life Cycle.

SASTtools

SAST Tools such as Fortify On Demand, CheckMarx’s CxSAST, Veracode, SonarQube, etc perform a static analysis of the application’s source code, examining the structure, syntax, and semantics.The analysis involves parsing the code to build an Abstract Syntax Tree (AST), allowing the tool to understand the relationships between different code elements. Oh, wait; what’s AST?

Abstract Syntax Tree : Abstract Syntax Tree (AST) is a fundamental concept in computer science, particularly in the field of programming languages and compiler theory. It is a hierarchical tree-like data structure that represents the syntactic structure of source code. It serves as an intermediary representation between the raw source code and the executable form

AST

AST is generated during the parsing phase of the compilation process. The parser analyzes the source code and builds the tree structure based on the language’s grammar rules. Then SAST Tools use predefined rules and patterns to identify known security vulnerabilities and coding patterns. These rules cover a wide range of issues, including common programming mistakes that could lead to security risks. There are various threat catalogs which they use to keep updated lists of vulnerabilities. Some of them are- OWASP Top Ten, OWASP Guidelines, CAPEC and CWE.

SASTWorking

By using SAST tools, we can identify security vulnerabilities such as:

Data flow analysis is also conducted by SAST tools to trace the movement of data through the application. This helps identify potential security vulnerabilities related to how data is processed and manipulated.

One of the most annoying disadvantage of using SAST Tools is that they generate a lot of False-Positives, marking code segments as vulnerable when they are not. Reviewers need to assess and triage findings to distinguish false positives from actual security issues. Some advanced SAST tools employ techniques like data flow tracking, symbolic execution, and abstract interpretation to enhance their ability to identify complex security issues. This helps in lowering these false-positive rates.

Software Composition Analysis-

Software Composition Analysis (SCA) is a security practice that involves analyzing and managing the third-party components and dependencies used in software applications. It aims to identify and mitigate security vulnerabilities, licensing issues, and other risks associated with the incorporation of external software components.

SCA Tools also identify vulnerable libraries, frameworks, and modules utilized by the application. SBOM (Software bill of Material) and SCA play complementary roles in providing transparency and security in the software supply chain. SCA tools contribute to the creation of SBOMs by supplying detailed information about software composition.

SCA tools maintain extensive databases that catalog vulnerabilities associated with different versions of libraries and frameworks. Through version tracking and correlation with these databases, SCA tools pinpoint potential risks in the software’s dependencies.

Some of the popular SCA tool are:

  1. Black Duck SCA
  2. Contrast SCA
  3. FOSSA
  4. Scantist SCA
  5. CxSCA
  6. Dependency-Check

Secrets Scanning-

Secret scanning tools are designed to identify and prevent the exposure of sensitive information, such as passwords, API keys, and other confidential data, within code repositories.

Some of the popular secret scanning tools are:

  1. GitLeaks
  2. GitGuardian
  3. sshgit!
  4. Whispers
  5. Trufflehog

How to choose a tool?

Choosing the right tools for Secure Code Review (SCR) is crucial for effective vulnerability identification and mitigation. Reviewer needs to first understand the project requirements and consider the programming languages, frameworks, and technologies used in the application. Some SCR tools specialize in certain languages, so ensure compatibility with the tech stack.

Reviewers also need to choose tools that seamlessly integrate into the development workflow. Look for tools that can be integrated with Integrated Development Environment (IDE), version control systems, and continuous integration/continuous deployment (CI/CD) pipelines. Also need to assess the tool’s coverage of security vulnerabilities. Different tools may focus on specific types of vulnerabilities (e.g., SQL injection, cross-site scripting). So, choose a tool that aligns with priority vulnerabilities, is scalable, has frequent updates and provides comprehensive coverage.

Resources

Conclusion

This is the end of Part-01 of Secure Code Review blogposts. In this, I have tried to cover basic things a beginner needs to know and learn in order to get started with actual secure code reviews. From the next part, I will try to cover more in-depth technically with topics ranging from regex patterns for SCR, semantic analysis, lexical analysis and how it would help in writing custom rules for various tools such as CodeQL, Semgrep and more. Further blogposts will also explore installations of major tools in SAST, SCA and IAST along with generating a universal report for end-to-end Secure Code Review. Until next time, happy hacking!