Code scanning is available for all public repositories on GitHub.com. Code scanning is also available for private repositories owned by organizations that use GitHub Enterprise Cloud and have a license for GitHub Advanced Security. For more information, see "About GitHub Advanced Security."
Use default setup to quickly configure CodeQL analysis for code scanning on your repository. Default setup automatically chooses the languages to analyze, query suite to run, and events that trigger scans. If you prefer, you can manually select the query suite to run and languages to analyze. After you enable CodeQL, GitHub Actions will execute workflow runs to scan your code. For more information, see "Configuring default setup for code scanning."
Use advanced setup to add the CodeQL workflow to your repository. This generates a customizable workflow file which uses the github/codeql-action to run the CodeQL CLI. For more information, see "Configuring advanced setup for code scanning."
GitHub experts, security researchers, and community contributors write and maintain the default CodeQL queries used for code scanning. The queries are regularly updated to improve analysis and reduce any false positive results.
When a CodeQL query pack is published to the GitHub Container registry, all the transitive dependencies required by the queries and a compilation cache are included in the package. This improves performance and ensures that running the queries in the pack gives identical results every time until you upgrade to a new version of the pack or the CLI.
Below, we include voluntary challenges, but it is highly recommended to do them while reading through the blog to get a better understanding of CodeQL, how to use it, and learn a few new tips and tricks about the tool.
CodeQL is a powerful static code analysis tool developed by Semmle (acquired by GitHub in 2019) and based on over decade of research by a team from Oxford University. CodeQL uses data flow analysis and taint analysis to find code errors, check code quality, and identify vulnerabilities. Currently, the supported languages include C/C++, C#, Go, Java, Kotlin, JavaScript, Python, Ruby, TypeScript, and Swift.
The key idea behind CodeQL is that it analyzes code as data by creating a database of facts about your program and then using a special query language, called QL, to query the database for vulnerable patterns.
Once we have the CodeQL database, we can ask it some questions (queries) about patterns that we want to find in the source code. For querying a CodeQL database, the QL query language is used. QL is an expressive, declarative, logical query language for identifying patterns in the database, that is vulnerabilities, for example, SQL injection. CodeQL queries are open-source, and anyone can create and contribute to CodeQL.
We mentioned earlier that to analyze the source code, a CodeQL database is needed. A CodeQL database is created automatically when you enable the code scanning with CodeQL action on a repository, but what if you would like to modify a query or query for specific artifacts yourself?
At a high level, the process works as follows: for each language CodeQL extracts the source code, converting it to understand it either by parsing the code directly or by instrumenting executions of a compiler that already exists for that language within a running build. The database itself is a relational representation of the code base, which contains information about the different source code elements, such as classes and functions, and puts each of those into a separate table of data. Each language has its own database schema, but generally there is a table for classes, a table for functions and so on, and relationships between these tables. CodeQL standard libraries for each language provide wrappers and layers around that database schema. We use the QL query language to query these tables and relationships. There are some differences in how CodeQL databases are extracted for each language and what information they contain stemming from the intrinsic differences between the languages. We will see these differences when using QL to query the databases, but at a high level that most people use, the differences are barely visible.
CodeQL databases already exist for many of the most popular open source projects on GitHub. GitHub hosts over 200,000 of them, and they are available to download by using the CodeQL extension in VS Code or GitHub via the GitHub API. If it happens that a CodeQL database is not available for your favorite open source repository, requesting it will trigger an attempt for database creation. Downloading a CodeQL database from GitHub is the quickest way to get started with analyzing a codebase. We will be using the CodeQL extension in VS Code to request a database in the challenges.
In this challenge, you will set up CodeQL for the challenges. You can do so via a preconfigured codespace (recommended) or locally. The preconfigured codespace is your own mini container in a virtual machine, which comes with everything you need to query a codebase using CodeQL: VS Code, CodeQL extension for VS Code, CodeQL command line tool preinstalled, and a pre-existing CodeQL database. The workspace will enable you to run your own CodeQL queries in the later challenges.
The CodeQL command line tool allows you to create databases from locally-sourced code. In this challenge, you will create a database for the vulnerable code we used in earlier exercises. Follow the instructions for the challenge 3 in the GitHubSecurityLab/codeql-zero-to-hero repository.
For interpreted languages in general, dependency source code will only be in the database if that dependency source code was part of the scanned codebase on the filesystem at database creation time. Most CodeQL libraries for interpreted languages are designed to reason about which APIs are called without having to see the source code of those APIs.
The database will contain some compile-time information about dependencies (for example, method signatures) but will not have the source code elements of the dependencies (unless the dependency was built from source code as part of the observed build). Most CodeQL libraries for compiled languages are designed to reason about which APIs are called using the signature information available at compile-time without having to see the source code of those APIs.
We have established that to get a CodeQL database for a certain repository, we can either download it from GitHub or create it yourself. Does it then make a difference if you download a CodeQL database of a project from GitHub or if you create one yourself? For the majority of the cases, not really.
Last note: CodeQL uses Static Analysis Results Interchange Format (SARIF) files to report on results of code scanning. The SARIF format has been widely accepted in the industry as a standardized output format, which allows for ease of sharing static analysis results with other tools.
The same trick works if you want to see all available types you can define in the from clause. Just write a comma next to the defined types in the from clause and press Ctrl + Space. If you use additional libraries for your query (in the import statement), the types defined in those libraries will also appear in the dropdown list.
If you have any questions, issues with challenges or with writing a CodeQL query, feel free to join and ask on the GitHub Security Lab server on Slack. The Slack server is open to anyone and gives you access to ask questions about issues with CodeQL, CodeQL modeling or anything else CodeQL related, and receive answers from a number of CodeQL engineers and security researchers from GitHub Security Lab. If you prefer to stay off Slack, feel free to ask any questions in CodeQL repository discussions or in GitHub Security Lab repository discussions.
GitHub Staff Engineer Sarah Vessels discusses her philosophy of code review, what separates good code review from bad, her strategy for finding and reviewing code, and how to get the most from reviews of her own code.
93ddb68554