Loading...
Loading...
Run CodeQL static analysis for security vulnerability detection, taint tracking, and data flow analysis. Use when asked to analyze code with CodeQL, create CodeQL databases, write custom QL queries, perform security audits, or set up CodeQL in CI/CD pipelines.
npx skill4agent add trailofbits/skills codeqlHTTP Handler → Input Parser → Business Logic → Database Query
↓ ↓ ↓ ↓
source transforms passes sink (SQL)request.paramdb.execute(query)# Check if CodeQL is installed
command -v codeql >/dev/null 2>&1 && echo "CodeQL: installed" || echo "CodeQL: NOT installed (run install steps below)"# macOS/Linux (Homebrew)
brew install --cask codeql
# Update
brew upgrade codeql# Download ToB query packs
codeql pack download trailofbits/cpp-queries trailofbits/go-queries
# Verify installation
codeql resolve qlpacks | grep trailofbitscodeql database create codeql.db --language=<LANG> [--command='<BUILD>'] --source-root=.| Language | | Build Required |
|---|---|---|
| Python | | No |
| JavaScript/TypeScript | | No |
| Go | | No |
| Ruby | | No |
| Rust | | Yes ( |
| Java/Kotlin | | Yes ( |
| C/C++ | | Yes ( |
| C# | | Yes ( |
| Swift | | Yes (macOS only) |
# List available query packs
codeql resolve qlpacks# SARIF output (recommended)
codeql database analyze codeql.db \
--format=sarif-latest \
--output=results.sarif \
-- codeql/python-queries:codeql-suites/python-security-extended.qls
# CSV output
codeql database analyze codeql.db \
--format=csv \
--output=results.csv \
-- codeql/javascript-queriescodeql database analyze codeql.db \
--format=sarif-latest \
--output=results.sarif \
-- trailofbits/go-queriesfrom Type x where P(x) select f(x)/**
* @name Find SQL injection vulnerabilities
* @description Identifies potential SQL injection from user input
* @kind path-problem
* @problem.severity error
* @security-severity 9.0
* @precision high
* @id py/sql-injection
* @tags security
* external/cwe/cwe-089
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
module SqlInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// Define taint sources (user input)
exists(source)
}
predicate isSink(DataFlow::Node sink) {
// Define dangerous sinks (SQL execution)
exists(sink)
}
}
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
from SqlInjectionFlow::PathNode source, SqlInjectionFlow::PathNode sink
where SqlInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "SQL injection from $@.", source.getNode(), "user input"| Field | Description | Values |
|---|---|---|
| Query type | |
| Issue severity | |
| CVSS score | |
| Confidence | |
// Predicates
predicate isUserInput(DataFlow::Node node) {
exists(Call c | c.getFunc().(Attribute).getName() = "get" and node.asExpr() = c)
}
// Transitive closure: + (one or more), * (zero or more)
node.getASuccessor+()
// Quantification
exists(Variable v | v.getName() = "password")
forall(Call c | c.getTarget().hasName("dangerous") | hasCheck(c))codeql pack init myorg/security-queriesmyorg-security-queries/
├── qlpack.yml
├── src/
│ └── SqlInjection.ql
└── test/
└── SqlInjectionTest.expectedname: myorg/security-queries
version: 1.0.0
dependencies:
codeql/python-all: "*"name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 1' # Weekly
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
matrix:
language: ['python', 'javascript']
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality
# Add custom queries/packs:
# queries: security-extended,./codeql/custom-queries
# packs: trailofbits/python-queries
- uses: github/codeql-action/autobuild@v3
- uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"codeql test run test/def vulnerable():
user_input = request.args.get("q") # Source
cursor.execute("SELECT * FROM users WHERE id = " + user_input) # Alert: sql-injection
def safe():
user_input = request.args.get("q")
cursor.execute("SELECT * FROM users WHERE id = ?", (user_input,)) # OK| Issue | Solution |
|---|---|
| Database creation fails | Clean build environment, verify build command works independently |
| Slow analysis | Use |
| Missing results | Check file exclusions, verify source files were parsed |
| Out of memory | Set |
| CMake source path issues | Adjust |
| Shortcut | Why It's Wrong |
|---|---|
| "No findings means the code is secure" | CodeQL only finds patterns it has queries for; novel vulnerabilities won't be detected |
| "This code path looks safe" | Complex data flow can hide vulnerabilities across 5+ function calls; trace the full path |
| "Small change, low risk" | Small changes can introduce critical bugs; run full analysis on every change |
| "Tests pass so it's safe" | Tests prove behavior, not absence of vulnerabilities; they test expected paths, not attacker paths |
| "The query didn't flag it" | Default query suites don't cover everything; check if custom queries are needed for your domain |