Code Review Techniques to Identify Security Flaws

Tutorial 5 of 5

1. Introduction

This tutorial aims to guide you through the process of performing a code review with a focus on identifying potential security flaws. Code reviews are a critical part of maintaining high-quality code in any project, and a special focus on security can prevent many common vulnerabilities.

Our focus will be on:
- Understanding the basics of a code review.
- Techniques and methodologies used in a code review.
- Identifying common security flaws through code review.

Prerequisites:
- Basic understanding of programming concepts.
- Familiarity with a programming language (examples in this tutorial will use Python).

2. Step-by-Step Guide

2.1 Understanding Code Review

Code review is the systematic examination of computer source code intended to find mistakes overlooked in the initial development phase, improving overall code quality.

2.2 Techniques and Methodologies

  • Manual Inspection: Reviewing code line by line to understand the logic and identify potential vulnerabilities.
  • Tool-Assisted Review: Using static code analysis tools to identify issues that can be automatically detected, like linters or security scanners.

2.3 Common Security Flaws

Some common security flaws to look for include:
- Injection Attacks: Code that incorporates untrusted input without sanitization may be vulnerable to injection attacks.
- Insecure Dependencies: Using third-party libraries or dependencies without verifying their security can introduce vulnerabilities.
- Insecure Data Storage: Insecure handling of sensitive data can lead to data leaks.

3. Code Examples

Example 1: SQL Injection

# This is a simple function to get user details from a database
# DO NOT use this approach, it's vulnerable to SQL injection
def get_user_details(user_id):
    query = f"SELECT * FROM users WHERE id = {user_id}"
    # The above statement is dangerous, an attacker can manipulate `user_id` to modify the query.
    # ...

Instead, use parameterized queries or ORM (Object Relational Mapping) libraries which usually handle such things automatically.

Example 2: Insecure Data Storage

# This function stores user password directly in a file
# DO NOT use this approach, it's insecure
def store_password(username, password):
    with open('passwords.txt', 'a') as file:
        file.write(f'{username}:{password}\n')
    # This approach is insecure as passwords are stored in plaintext. 
    # ...

Instead, you should always hash and salt passwords before storing them.

4. Summary

In this tutorial, you've learned the basics of code review, some common techniques and methodologies, and how to identify a couple of common security flaws. The next steps could be to delve deeper into each of these vulnerabilities, learning how to mitigate them, and exploring more types of security flaws.

5. Practice Exercises

Exercise 1:

Review the following code snippet and identify any potential security flaws.

def login(username, password):
    if username in users and users[username] == password:
        return True
    return False

Exercise 2:

What other security issues could arise if an application uses insecure third-party libraries?

Solutions

  1. The login function is vulnerable to brute force attacks as there is no limit to the number of attempts a user can make. Additionally, it's storing and comparing passwords in plaintext which is insecure.
  2. Insecure third-party libraries can introduce various vulnerabilities including but not limited to: Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), Remote Code Execution (RCE), and data leaks.