Analyze vulnerabilities in your code with CodeQL locally

Luis Rangel
6 min readApr 19, 2023

--

GitHub provides us with different tools that allow us to also execute this type of task. Today I want to talk to you about one of them called CodeQL, which helps us to analyze the code in search of vulnerabilities. For this article I want to show you how to use it from your local machine.

What is CodeQL?
Before playing with it, let me tell you that CodeQL belongs to the group of tools called SAST (Static Application Security Testing) and GitHub offers it for free for all public repositories on GitHub.com and through the GitHub Advanced Security license. This generates a database with your code on which queries can be made for the different languages supported today. There are many already generated by the CodeQL team ready to use, although you can also create your own. This tool can be used in different ways: using GitHub Actions, the command line, or by integrating with third-party CI tools. In this article I want to show you how to use it through the command line.

Important: this tool requires a GitHub Advanced Security license in those cases that are not academic or open source.

Local CodeQL installation and configuration
In this example I am going to use the binaries for MacOs, but you should know that they are also available for Windows and Linux. The first thing I have to do is download the latest version for my operating system, I create a folder called codeql-home where I will store the resulting directory and unzip the binaries there:

# Download CodeQL for mac with cURL
curl -L https://github.com/github/codeql-cli-binaries/releases/download/v2.12.7/codeql-osx64.zip -o codeql-osx64.zip
# Create a folder for CodeQL
mkdir $HOME/codeql-home
# Unzip the file in $HOME/codeql-home folder
unzip codeql-osx64.zip -d $HOME/codeql-home && rm codeql-osx64.zip

To get the list of versions: https://github.com/github/codeql-action/releases

The next thing you will need are the queries already built by the CodeQL team that will make it easier for you to analyze the code. To do this, in the same codeql-home folder, clone the repository where they are located, but rename it so that its name does not match the binary directory:

# Download queries and add them to the CodeQL home folder
cd $HOME/codeql-home
git clone --recursive https://github.com/github/codeql.git codeql-repo
  • Or using by git submodule update --init --remote after cloning.
  • Use git submodule update --remote regularly to keep the submodules up to date.
  • Setting up a CodeQL workspace.

Inside the codeql-home folder you should now have two directories: codeql and codeql-repo at the same level:

To check that everything works correctly, export to the PATH environment variable the path of the codeql-home/codeql directory:

# Add the CodeQL home folder to the PATH
export PATH=$PATH:$HOME/codeql-home/codeql

And run these two commands:

# Check the configuration
codeql resolve languages
codeql resolve qlpacks

The first of them will return a list with the supported languages:

codeql resolve languages

The second query packs detected in the codeql-repo directory:

codeql resolve qlpacks

Now you are ready to search for vulnerabilities in your code 😃

Create a database of your code with CodeQL
Now that you have the tool downloaded and configured, the next thing to do is create the database that CodeQL needs to check for potential vulnerabilities that your code may have. To do this, position yourself in the repository you want to analyze and execute the following command:

# Create a database of my code
codeql database create codeqldb --language=javascript

In this case I am using code developed with Node.JS, so the language will be javascript. Once the process is finished, a directory called codeqldb will have been created with the database.

Query the database
The next step is to perform queries on the generated database. But what queries do I do and how? Thanks to the repository that you have cloned, we can use different sets of queries built by the CodeQL team, in QL language, which will make our lives easier. They have also been grouped into three categories:

  • Code Scanning: These are the queries that are launched by default when you run the tool from GitHub.
  • Security Extended: queries of less severity and precision than the previous ones.
  • Security and quality: In addition to security queries, it also launches code quality queries.
    You can execute each of them through the following commands:
export CODEQL_SUITES_PATH=$HOME/codeql-home/codeql-repo/javascript/ql/src/codeql-suites
export RESULTS_FOLDER=codeql-results
mkdir -p $RESULTS_FOLDER
# Code Scanning suite: Queries run by default in CodeQL code scanning on GitHub.
codeql database analyze codeqldb $CODEQL_SUITES_PATH/javascript-code-scanning.qls \
--format=sarifv2.1.0 \
--output=$RESULTS_FOLDER/javascript-code-scanning.sarif

# Security extended suite: Queries of lower severity and precision than the default queries
codeql database analyze codeqldb $CODEQL_SUITES_PATH/javascript-security-extended.qls \
--format=sarif-latest \
--output=$RESULTS_FOLDER/javascript-security-extended.sarif

# Security and quality suite: Queries of lower severity and precision than the default queries
codeql database analyze codeqldb $CODEQL_SUITES_PATH/javascript-security-and-quality.qls \
--format=sarif-latest \
--output=$RESULTS_FOLDER/javascript-security-and-quality.sarif

Each of these commands will generate a file in SARIF format with the results of the queries. The process may take a while, depending on the power of your equipment.

View query results
In order to easily view the result of each of the files I have used the Sarif Viewer extension. However, in order for it to know how to correctly interpret the files, the value of the $schema property must be modified from https://json.schemastore.org/sarif-2.1.0.json to http://json.schemastore.org/ sarif-2.1.0-rtm.1 as of today. For this I have used jq to replace the value in a simple way:

# If you want to see the result with Sarif Viewer you have to change the schema to http://json.schemastore.org/sarif-2.1.0-rtm.1
cat $RESULTS_FOLDER/javascript-code-scanning.sarif | jq '.["$schema"] = "http://json.schemastore.org/sarif-2.1.0-rtm.1"' > $RESULTS_FOLDER/javascript-code-scanning-fixed-schema.sarif
cat $RESULTS_FOLDER/javascript-security-extended.sarif | jq '.["$schema"] = "http://json.schemastore.org/sarif-2.1.0-rtm.1"' > $RESULTS_FOLDER/javascript-security-extended-fixed-schema.sarif
cat $RESULTS_FOLDER/javascript-security-and-quality.sarif | jq '.["$schema"] = "http://json.schemastore.org/sarif-2.1.0-rtm.1"' > $RESULTS_FOLDER/javascript-security-and-quality-fixed-schema.sarif

Once this change is made, and the extension is installed in your Visual Studio Code, if you open, for example, the last of the files, javascript-security-and-quality-fixed-schema.sarif, which will possibly have the most information, you will see a result similar to this:

CodeQL results with Sarif Viewer

And if you click on any of the lines it will take you to the code and show you the trouble spots.

Article based on: https://www.returngis.net/2022/03/analizar-vulnerabilidades-en-tu-codigo-con-codeql-en-local/

--

--

Luis Rangel
Luis Rangel

Written by Luis Rangel

Hi I’m Luis Rangel, a Full Stack Developer and a newbie on a loop 🚀 from Guatemala, currently, I’m a Team Member Telus International🙍🏽‍♂️ @luisrangelc.