Find Insecure Code With CodeQL Before You Commit

You have a bunch of code to commit for your Docker image so that you can update your app that runs in Amazon EKS. STOP! First scan your source code with CodeQL before you commit and push!

Photo by Muhammad Zaqy Al Fattah on Unsplash

The Solution

In this tutorial, we’ll go over scanning C# source code for vulnerabilities in a development environment using the CodeQL CLI.

Remember, for any example solution from AWS with .NET, we focus on the code that exemplifies the problem we are trying to solve. We don’t include logging, input validation, exception handling, etc., and we embed the configuration data within classes instead of using environment variables, configuration files, key/value stores and the like. These items should not be skipped for proper solutions.

Prerequisites

To complete this tutorial, you will need the .NET CLI which is included in the .NET SDK. In addition, you will need to install the CodeQL CLI.

Warning: some AWS services may have fees associated with them.

Our Dev Environment

This tutorial was developed using Ubuntu 22.10, .NET 7 SDK, CodeQL CLI 2.13.1 and Visual Studio Code 1.78.2. Some commands/constructs may vary across platforms.

What is CodeQL?


CodeQL is a type of static application security testing (SAST) scanner that scans source code for vulnerabilities. A vulnerability is a weakness in an application that allows an attacker to cause harm to the application’s owner, the application users, and/or organizations that rely on the application, et. al. Popular attacks include: SQL injection, cross-site scripting and brute force attacks. Using a tool like CodeQL early in the development process can save time, money and possibly prevent damage to a company’s reputation.

Create a .NET Test App


The first thing we’ll do is create a .NET test app using the .NET CLI which is part of the .NET SDK. Notice the name of the app, “dotnet-app”, is specified using the -n parameter in the command below.

$ dotnet new webapi -n dotnet-app

Setup the CodeQL CLI


Now that we have an app to test, Let’s get the CodeQL CLI ready to go.

Download the CodeQL CLI

Point your browser to the CodeQL releases page on GitHub and download the archive that corresponds to the platform that you are using. For this tutorial, we are downloading and using the release specified with “linux64” in the filename.

Once the file has been downloaded, extract the files from the archive. For our Linux system, we’ll use the unzip command.

$ unzip codeql-linux64.zip -d ~/bin/codeql/

We are going to take one more step and add the codeql executable to our PATH variable so that we can call “codeql” from any location within the OS. On our Ubuntu system we can accomplish this by modifying the PATH variable in the ~/.profile. file by appending the path of the codeql executable.

Test the CodeQL CLI

We can test the CodeQL CLI by checking the version at the command line.

$ codeql --version

If everything is setup correctly, We should see output something like this:

CodeQL command-line toolchain release 2.13.1.
Copyright (C) 2019-2023 GitHub, Inc.
Unpacked in: /home/user/bin/codeql
Analysis results depend critically on separately distributed query and
extractor modules. To list modules that are visible to the toolchain,
use ‘codeql resolve qlpacks’ and ‘codeql resolve languages’.

You can further test by using the following command to get a list of the languages that can be used.

$ codeql resolve languages

Download the CodeQL Language Packs

To download precompiled queries for cs, use the following command:

$ codeql pack download codeql/cs-queries

Scan the Code for Vulnerabilities

Now that we have CodeQL downloaded and configured, we can start to scan code.

Create a Directory for the CodeQL Database

The first thing we will need to do is create a directory to house the CodeQL database.

$ mkdir ~/codeql-dbs

Create the CodeQL Database

Now that we have a location for the database, let’s change to the directory of the test app that we created earlier as CodeQL will need to compile the app in order to build the code database for it.

$ cd ~/source/dotnet-app

CodeQL requires a clean environment free of previous build artifacts. Let’s ensure the environment is clean using the .NET CLI.

$ dotnet clean

Now we are set to create the CodeQL database with the following command:

Parameters:
~/codeql-dbs/dotnet-app: CodeQL database location
language: The language to scan. In this case, C# (cs)
command: use your app’s build commands for compiled languages like C#. Here our command is simple, “dotnet build”.

$ codeql database create ~/codeql-dbs/dotnet-app --language=cs --command="dotnet build"

If everything goes to plan, the output of the database create command will end with something like this:

“Successfully created database at /home/user/codeql-dbs/dotnet-app.”

Create a Directory for the CodeQL Output

CodeQL aggregates its findings in an output file. Let’s create a directory to house the output file.

$ mkdir ./codeql-output/

Code Analysis

Running the following command will instruct CodeQL to analyze the code using the previously built database for, “dotnet-app.”

Parameters:
~/codeql-dbs/dotnet-app: The CodeQL database location.
format: The output format. (Also supports SARIF and graph formats)
output: The path to the output file

$ codeql database analyze ~/codeql-dbs/dotnet-app --format="csv"  
--output="./codeql-output/scan.csv"

When CodeQL completes its analysis, the console should display a message like:

Shutting down query evaluator.
Interpreting results.
Analysis produced the following diagnostic data:
| Diagnostic | Summary |
+——————————+———–+
| Compilation message | 3 results |
| Successfully extracted files | 6 results |
Analysis produced the following metric data:
| Metric | Value |
+—————————————-+——–+
| Total lines of C# code in the database | 13,700 |

View the CodeQL Analysis Output

$ nano ./codeql-output/scan.csv

Summary

We have concluded this tutorial where you have learned how to scan C# source code for vulnerabilities in a development environment using the CodeQL CLI.

Now, before you commit code for the Docker image that you run in EKS – scan it for vulnerabilities with CodeQL before you commit.

Want to know more about the tech in this article?  Checkout these resources:

.NET CLI, .NET SDK, CodeQL, CodeQL CLI