codeql
Install this skill
npx skills add trailofbits/skillsWorks across Claude Code, Cursor, Codex, Copilot & Antigravity
CodeQL is an analysis engine that treats source code as data. By building a relational database representation of a codebase, it allows security engineers to write declarative queries to find complex bugs and structural vulnerabilities. Unlike simple text-based grep tools, it tracks data flow and control flow across files and function boundaries, making it effective for identifying injection points, memory corruption, and logic errors. It relies on a specific query language (QL) based on object-oriented and logic programming concepts. Because it requires a compilation trace to extract facts about code, it functions best in environments where build processes are accessible. Users define patterns as logic predicates to identify variants of known flaws, enabling programmatic detection across large-scale software architectures.
When to Use This Skill
- β’Identifying cross-file data tainted inputs leading to security sinks
- β’Automating regression testing for specific vulnerability classes
- β’Enforcing internal secure coding standards through custom query enforcement
- β’Analyzing deep logic flaws that require multi-step execution tracing
How to Invoke This Skill
Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:
- βFind data flow vulnerabilities in this C++ project
- βWrite a CodeQL query to detect SQL injection
- βAnalyze this codebase for sink reachability
- βCreate a CodeQL database for my build
- βExecute custom QL queries against this repository
Pro Tips
- π‘Leverage the agent to help generate initial CodeQL queries. Describe the vulnerability pattern or code structure you're looking for, and let the AI draft a starting point.
- π‘For compiled languages, ensure your build process is robust and reproducible; CodeQL's effectiveness hinges on a correctly generated database.
- π‘Integrate CodeQL scans into your CI/CD pipeline using the agent to automate early detection of new vulnerabilities introduced in pull requests.
What this skill does
- β’Interprocedural data flow tracking
- β’Abstract Syntax Tree (AST) exploration
- β’Declarative bug pattern definition using QL
- β’SARIF output for integration with CI/CD and IDEs
- β’Multi-language support via standardized query libraries
When not to use it
- βPerforming quick syntax checks or simple regex-based code matching
- βAnalyzing projects where the build system cannot be fully executed
- βAnalyzing code where build time latency is unacceptable
Example workflow
- Clean the build directory to ensure accurate tracing
- Execute the database creation command matching the language
- Download required query packs from the package registry
- Run targeted queries against the generated database
- Export findings to SARIF format for review in a code editor
Prerequisites
- βAccess to the project build environment
- βWorking knowledge of the QL language
- βBasic understanding of AST structures
Pitfalls & limitations
- !High initial learning curve for the QL syntax
- !Dependency on the accuracy of the build compilation trace
- !Complex queries can require significant memory and time to process
- !Incomplete standard libraries for niche or proprietary languages
FAQ
How it compares
While manual security auditing relies on individual inspection, CodeQL automates the search for logic flaws across the entire codebase by querying the underlying data structures, making it scalable where manual review is impossible.
Source & trust
π Full skill instructions β original source: trailofbits/skills
CodeQL is a powerful static analysis framework that allows developers and security researchers to query a codebase for specific code patterns. The CodeQL standard libraries implement support for both inter- and intraprocedural control flow and data flow analysis. However, the learning curve for writing custom queries is steep, and documentation for the CodeQL standard libraries is still scant.
## When to Use
**Use CodeQL when:**
- You need interprocedural control flow and data flow queries across the entire codebase
- Fine-grained control over the abstract syntax tree, control flow graph, and data flow graph is required
- You want to prevent introduction of known bugs and security vulnerabilities into the codebase
- You have access to source code and third-party dependencies (and can build compiled languages)
- The bug class requires complex analysis beyond single-file pattern matching
**Consider alternatives when:**
- Single-file pattern matching is sufficient β Consider Semgrep
- You don't have access to source code or can't build the project
- Analysis time is critical (complex queries may take a long time)
- You need to analyze a closed-source repository without a GitHub Advanced Security license
- The language is not supported by CodeQL
## Quick Reference
| Task | Command |
|------|---------|
| Create database (C/C++) |
codeql database create codeql.db --language=cpp --command='make -j8' || Create database (Go) |
codeql database create codeql.db --language=go || Create database (Java/Kotlin) |
codeql database create codeql.db --language=java || Create database (JavaScript/TypeScript) |
codeql database create codeql.db --language=javascript || Create database (Python) |
codeql database create codeql.db --language=python || Analyze database |
codeql database analyze codeql.db --format=sarif-latest --output=results.sarif -- codeql/cpp-queries || List installed packs |
codeql resolve qlpacks || Download query pack |
codeql pack download trailofbits/cpp-queries || Run custom query |
codeql query run --database codeql.db -- path/to/Query.ql || Test custom queries |
codeql test run -- path/to/test/pack/ |## Installation
### Installing CodeQL
CodeQL can be installed manually or via Homebrew on macOS/Linux.
**Manual Installation:**
Navigate to the [CodeQL release page](https://github.com/github/codeql-action/releases) and download the latest bundle for your architecture. The bundle contains the
codeql binary, query libraries for supported languages, and pre-compiled queries.**Using Homebrew:**
brew install --cask codeql### Keeping CodeQL Up to Date
CodeQL is under active development. Update regularly to benefit from improvements.
**Manual installation:** Download new updates from the [CodeQL release page](https://github.com/github/codeql-action/releases).
**Homebrew installation:**
brew upgrade codeql### Verification
codeql --version## Core Workflow
### Step 1: Build a CodeQL Database
To build a CodeQL database, you typically need to be able to build the corresponding codebase. Ensure the codebase is in a clean state (e.g., run
make clean, go clean, or similar).**For compiled languages (C/C++, Swift):**
codeql database create codeql.db --language=cpp --command='make -j8'If using CMake or out-of-source builds, add
--source-root to specify the source file tree root:codeql database create codeql.db --language=cpp --source-root=/path/to/source --command='cmake --build build'**For interpreted languages (Python, JavaScript):**
codeql database create codeql.db --language=python**For languages with auto-detection (Go, Java):**
codeql database create codeql.db --language=goFor complex build systems, use the
--command argument to pass the build command.### Step 2: Analyze the Database
Run pre-compiled query packs on the database:
codeql database analyze codeql.db --format=sarif-latest --output=results.sarif -- codeql/cpp-queriesOutput formats include SARIF and CSV. SARIF results can be viewed with the [VSCode SARIF Explorer extension](https://marketplace.visualstudio.com/items?itemName=trailofbits.sarif-explorer).
### Step 3: Review Results
SARIF files contain findings with location, severity, and description. Import into your IDE or CI/CD pipeline for review and remediation.
### Installing Third-Party Query Packs
Published query packs are identified by scope/name/version. For example:
codeql pack download trailofbits/cpp-queries trailofbits/go-queriesFor Trail of Bits public CodeQL queries, see [trailofbits/codeql-queries](https://github.com/trailofbits/codeql-queries).
## How to Customize
### Writing Custom Queries
CodeQL queries use a declarative, object-oriented language called QL with Java-like syntax and SQL-like query expressions.
**Basic query structure:**
import cpp
from FunctionCall call
where call.getTarget().getName() = "memcpy"
select call.getLocation(), call.getArgument(0)This selects all expressions passed as the first argument to
memcpy.**Creating a custom class:**
import cpp
class MemcpyCall extends FunctionCall {
MemcpyCall() {
this.getTarget().getName() = "memcpy"
}
Expr getDestination() {
result = this.getArgument(0)
}
Expr getSource() {
result = this.getArgument(1)
}
Expr getSize() {
result = this.getArgument(2)
}
}
from MemcpyCall call
select call.getLocation(), call.getDestination()### Key Syntax Reference
| Syntax/Operator | Description | Example |
|-----------------|-------------|---------|
|
from Type x where P(x) select f(x) | Query: select f(x) for all x where P(x) is true | from FunctionCall call where call.getTarget().getName() = "memcpy" select call ||
exists(...) | Existential quantification | exists(FunctionCall call \| call.getTarget() = fun) ||
forall(...) | Universal quantification | forall(Expr e \| e = arg.getAChild() \| e.isConstant()) ||
+ | Transitive closure (1+ times) | start.getASuccessor+() ||
* | Reflexive transitive closure (0+ times) | start.getASuccessor*() ||
result | Special variable for method/function output | result = this.getArgument(0) |### Example: Finding Unhandled Errors
import cpp
/**
* @name Unhandled error return value
* @id custom/unhandled-error
* @description Function calls that return error codes that are not checked
* @kind problem
* @problem.severity warning
* @precision medium
*/
predicate isErrorReturningFunction(Function f) {
f.getName().matches("%error%") or
f.getName().matches("%Error%")
}
from FunctionCall call
where
isErrorReturningFunction(call.getTarget()) and
not exists(Expr parent |
parent = call.getParent*() and
(parent instanceof IfStmt or parent instanceof SwitchStmt)
)
select call, "Error return value not checked"### Adding Query Metadata
Query metadata is defined in an initial comment:
/**
* @name Short name for the issue
* @id scope/query-name
* @description Longer description of the issue
* @kind problem
* @tags security external/cwe/cwe-123
* @problem.severity error
* @precision high
*/**Required fields:**
-
name: Short string identifying the issue-
id: Unique identifier (lowercase letters, numbers, /, -)-
description: Longer description (a few sentences)-
kind: Either problem or path-problem-
problem.severity: error, warning, or recommendation-
precision: low, medium, high, or very-high**Output format requirements:**
-
problem queries: Output must be (Location, string)-
path-problem queries: Output must be (DataFlow::Node, DataFlow::PathNode, DataFlow::PathNode, string)### Testing Custom Queries
Create a test pack with
qlpack.yml:name: scope/name-test
version: 0.0.1
dependencies:
codeql-query-pack-to-test: "*"
extractor: cppCreate a test directory (e.g.,
MemcpyCall/) containing:-
test.c: Source file with code pattern to detect-
MemcpyCall.qlref: Text file with path to the query-
MemcpyCall.expected: Expected outputRun tests:
codeql test run -- path/to/test/pack/If
MemcpyCall.expected is missing or incorrect, an MemcpyCall.actual file is created. Review it, and if correct, rename to MemcpyCall.expected.## Advanced Usage
### Creating New Query Packs
Initialize a query pack:
codeql pack init <scope>/<name>This creates a
qlpack.yml file:---
library: false
warnOnImplicitThis: false
name: <scope>/<name>
version: 0.0.1Add standard library dependencies:
codeql pack add codeql/cpp-allCreate a workspace file (
codeql-workspace.yml) for the CLI to work correctly.Install dependencies:
codeql pack installConfigure the CLI to find your queries by creating
~/.config/codeql/config:--search-path /full/path/to/your/codeql/root/directory### Recommended Directory Structure
.
βββ codeql-workspace.yml
βββ cpp
β βββ lib
β β βββ qlpack.yml
β β βββ scope
β β βββ security
β β βββ someLibrary.qll
β βββ src
β β βββ qlpack.yml
β β βββ suites
β β β βββ scope-cpp-code-scanning.qls
β β β βββ scope-cpp-security.qls
β β βββ security
β β βββ AppSecAnalysis
β β βββ AppSecAnalysis.c
β β βββ AppSecAnalysis.qhelp
β β βββ AppSecAnalysis.ql
β βββ test
β βββ qlpack.yml
β βββ query-tests
β βββ security
β βββ AppSecAnalysis
β βββ AppSecAnalysis.c
β βββ AppSecAnalysis.expected
β βββ AppSecAnalysis.qlref### Recursion and Transitive Closures
**Recursive predicate:**
predicate isReachableFrom(BasicBlock start, BasicBlock end) {
start = end or isReachableFrom(start.getASuccessor(), end)
}**Using transitive closure (equivalent):**
predicate isReachableFrom(BasicBlock start, BasicBlock end) {
end = start.getASuccessor*()
}Use
* for zero or more applications, + for one or more.### Excluding Individual Files
CodeQL instruments the build process. If object files already exist and are up-to-date, corresponding source files won't be added to the database. This can reduce database size but means CodeQL has only partial knowledge about excluded files and cannot reason about data flow through them.
**Recommendation:** Include third-party libraries and filter issues based on location rather than excluding files during database creation.
### Editor Support
**VSCode:** [CodeQL extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql) provides LSP support, syntax highlighting, query running, and AST visualization.
**Neovim:** [codeql.nvim](https://github.com/pwntester/codeql.nvim) provides similar functionality.
**Helix/Other editors:** Use the CodeQL LSP server and [Tree-sitter grammar for CodeQL](https://github.com/tree-sitter/tree-sitter-ql).
**VSCode Quick Query:** Use "CodeQL: Quick Query" command to run single queries against a database.
**Debugging queries:** Add database source to workspace, then use "CodeQL: View AST" to display the AST for individual nodes.
## Configuration
### CodeQL Standard Libraries
CodeQL standard libraries are language-specific. Refer to API documentation:
- [C and C++](https://codeql.github.com/codeql-standard-libraries/cpp/)
- [Go](https://codeql.github.com/codeql-standard-libraries/go/)
- [Java and Kotlin](https://codeql.github.com/codeql-standard-libraries/java/)
- [JavaScript and TypeScript](https://codeql.github.com/codeql-standard-libraries/javascript/)
- [Python](https://codeql.github.com/codeql-standard-libraries/python/)
- [C#](https://codeql.github.com/codeql-standard-libraries/csharp/)
- [Ruby](https://codeql.github.com/codeql-standard-libraries/ruby/)
- [Swift](https://codeql.github.com/codeql-standard-libraries/swift/)
### Supported Languages
CodeQL supports C/C++, C#, Go, Java, Kotlin, JavaScript, TypeScript, Python, Ruby, and Swift. Check [supported languages and frameworks](https://codeql.github.com/docs/codeql-overview/supported-languages-and-frameworks) for details.
## CI/CD Integration
### GitHub Actions
Enable code scanning from "Code security and analysis" in repository settings. Choose default or advanced setup.
**Advanced setup workflow:**
name: "CodeQL"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '34 10 * * 6'
jobs:
analyze:
name: Analyze
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"For compiled languages, replace autobuild with custom build commands:
- run: |
make -j8### Using Custom Queries in CI
Specify query packs and queries in the "Initialize CodeQL" step:
- uses: github/codeql-action/init@v3
with:
queries: security-extended,security-and-quality
packs: trailofbits/cpp-queriesFor repository-local queries:
- uses: github/codeql-action/init@v3
with:
queries: ./codeql/UnhandledError.ql
packs: trailofbits/cpp-queriesNote the
. prefix for repository-relative paths. All queries must be part of a query pack with a qlpack.yml file.### Testing Custom Queries in CI
name: Test CodeQL queries
on: [push, pull_request]
jobs:
codeql-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: init
uses: github/codeql-action/init@v3
- uses: actions/cache@v4
with:
path: ~/.codeql
key: ${{ runner.os }}-${{ runner.arch }}-${{ steps.init.outputs.codeql-version }}
- name: Run tests
run: |
${{ steps.init.outputs.codeql-path }} test run ./path/to/query/tests/This workflow caches query extraction and compilation for faster subsequent runs.
## Common Mistakes
| Mistake | Why It's Wrong | Correct Approach |
|---------|----------------|------------------|
| Not building project before creating database | CodeQL won't have complete information | Run
make clean or equivalent, then build with CodeQL || Excluding third-party libraries from database | Prevents interprocedural analysis through library code | Include libraries, filter results by location |
| Using relative imports in query packs | Causes resolution issues | Use absolute imports from standard libraries |
| Not adding query metadata | SARIF output lacks severity, description | Always add metadata comment with required fields |
| Forgetting workspace file | CLI won't find query packs | Create
codeql-workspace.yml in root directory |## Limitations
- **Licensing:** Closed-source repositories require GitHub Enterprise or Advanced Security license
- **Build requirement:** Compiled languages must be buildable; no build = incomplete database
- **Performance:** Complex interprocedural queries can take a long time on large codebases
- **Language support:** Limited to CodeQL-supported languages and frameworks
- **Learning curve:** Steep learning curve for writing custom queries; documentation is scant
- **Single-language databases:** Each database is for one language; multi-language projects need multiple databases
## Related Skills
| Skill | When to Use Together |
|-------|---------------------|
| **semgrep** | Use Semgrep first for quick pattern-based analysis, then CodeQL for deeper interprocedural analysis |
| **sarif-parsing** | For processing CodeQL SARIF output in custom CI/CD pipelines |
## Resources
### Trail of Bits Blog Posts on CodeQL
- [Look out! Divergent representations are everywhere!](https://blog.trailofbits.com/2022/11/10/divergent-representations-variable-overflows-c-compiler/)
- [Finding unhandled errors using CodeQL](https://blog.trailofbits.com/2022/01/11/finding-unhandled-errors-using-codeql/)
- [Detecting iterator invalidation with CodeQL](https://blog.trailofbits.com/2020/10/09/detecting-iterator-invalidation-with-codeql/)
### Learning Resources
- [CodeQL zero to hero part 1: The fundamentals of static analysis for vulnerability research](https://github.blog/2023-03-31-codeql-zero-to-hero-part-1-the-fundamentals-of-static-analysis-for-vulnerability-research/)
- [QL language tutorials](https://codeql.github.com/docs/writing-codeql-queries/ql-tutorials/)
- [GitHub Security Lab CodeQL CTFs](https://securitylab.github.com/ctf/)
### Writing Custom CodeQL Queries
- [Practical introduction to CodeQL](https://jorgectf.github.io/blog/post/practical-codeql-introduction/)
- [Sharing security expertise through CodeQL packs (Part I)](https://github.blog/2022-04-19-sharing-security-expertise-through-codeql-packs-part-i/)
### Video Resources
- [Trail of Bits: Introduction to CodeQL - Examples, Tools and CI Integration](https://www.youtube.com/watch?v=rQRlnUQPXDw)
- [Finding Security Vulnerabilities in C/C++ with CodeQL](https://www.youtube.com/watch?v=eAjecQrfv3o)
- [Finding Security Vulnerabilities in JavaScript with CodeQL](https://www.youtube.com/watch?v=pYzfGaLTqC0)
- [Finding Security Vulnerabilities in Java with CodeQL](https://www.youtube.com/watch?v=nvCd0Ee4FgE)
### Using CodeQL for Vulnerability Discovery
- [Clang checkers and CodeQL queries for detecting untrusted pointer derefs and tainted loop conditions](https://www.zerodayinitiative.com/blog/2022/2/22/clang-checkers-and-codeql-queries-for-detecting-untrusted-pointer-derefs-and-tainted-loop-conditions)
- [Heap exploitation with CodeQL](https://github.com/google/security-research/blob/master/analysis/kernel/heap-exploitation/README.md)
- [Interesting kernel objects dashboard](https://lookerstudio.google.com/reporting/68b02863-4f5c-4d85-b3c1-992af89c855c/page/n92nD)
### CodeQL in CI/CD
- [Blue-teaming for Exiv2: adding custom CodeQL queries to code scanning](https://github.blog/2021-11-16-adding-custom-codeql-queries-code-scanning/)
- [Best practices on rolling out code scanning at enterprise scale](https://github.blog/2022-09-28-best-practices-on-rolling-out-code-scanning-at-enterprise-scale/)
- [Fine tuning CodeQL scans using query filters](https://colinsalmcorner.com/fine-tuning-codeql-scans/)
How to Use This Skill Unit
Option A: Project-Specific (Recommended)
- Click "Download" above
- In your project, create the directory:
.agent/skills/codeql/ - Save the file as
SKILL.md - The agent will automatically discover the skill based on its description.
Option B: Global Installation (All Agents)
Save the file to these locations to make it available across all projects:
- Claude Code:
~/.claude/skills/trailofbits/skills/codeql/SKILL.md - Cursor:
~/.cursor/skills/trailofbits/skills/codeql/SKILL.md - Antigravity:
~/.gemini/antigravity/skills/trailofbits/skills/codeql/SKILL.md
π Install with CLI:npx skills add trailofbits/skills