| description | Common guidance for developing CodeQL queries across all supported languages |
|---|
This prompt provides common guidance for developing CodeQL queries across all supported languages, while language-specific prompts reference this common guidance and add language-specific details.
Your generated CodeQL queries will be evaluated on:
-
QL Code Quality:
- Critical: Query must compile without errors. Invalid CodeQL queries cannot be run and have negative code quality.
- Important: Minimize warning-level diagnostics (deprecated elements, style guide deviations)
- Best Practice: Follow CodeQL naming conventions and idioms
-
Query Results Accuracy:
- When tested against provided test code, actual results should match expected results
- Minimize false positives (flagging correct code as problematic)
- Minimize false negatives (missing actual problems)
-
Performance:
- Use efficient predicates and avoid unnecessary joins
- Leverage built-in library predicates when available
- Consider query complexity for large codebases
/**
* @name QueryName
* @description Brief description of what the query detects
* @kind problem
* @problem.severity warning
* @security-severity 5.0
* @precision medium
* @id language/query-id
* @tags security
* maintainability
*/
import language
from ElementType element
where
// Query logic here
problematicCondition(element)
select element, "Description of the issue found"@name: Human-readable query name@description: Clear explanation of what patterns are detected@kind: Usuallyproblemfor security/quality queries@problem.severity:error,warning, orrecommendation@precision:high,medium, orlowbased on false positive rate@id: Format aslanguage/category-name(e.g.,java/sql-injection)@tags: Relevant categories (security, correctness, maintainability, etc.)
Follow this workflow for reliable query development:
- Create New Query Scaffolding: Use the qlt query generate new-query command to create the initial query structure.
- Generate Query Plan: Define what patterns to detect
- Create Test Cases: Write both compliant and non-compliant code examples
- Extract Test Database: Create minimal CodeQL database from test code
- Analyze AST: Use PrintAST queries to understand code structure
- Implement Query: Write QL code based on AST analysis
- Compile and Test: Ensure query compiles and produces expected results
- Iterate: Refine based on test results and performance
For detailed TDD workflow, see Test-Driven QL Development.
For iterative development workflows involving multiple query executions, consider using the persistent query server:
Use codeql execute query-server2 when:
- Running multiple queries during development iterations
- Executing PrintAST and other diagnostic queries repeatedly
- Working in an IDE or editor with CodeQL integration
- Need to minimize query execution latency across multiple runs
- Working with template-based queries (contextual queries)
Use individual codeql query run commands when:
- Running single queries for final validation
- Scripting or automation scenarios
- Simple one-off query execution
- CLI-based workflows without IDE integration
The query-server2 provides several performance advantages:
- Persistent process: Eliminates startup overhead for multiple executions
- Shared compilation cache: Compiled queries and libraries cached across runs
- Template support: Efficient handling of contextual queries with variables
- Quick evaluation: Rapid evaluation of query fragments during development
For complete query-server2 usage details, see codeql execute query-server2.
Most queries will need these imports:
import language // Core language support
import language.DataFlow // Data flow analysis (if needed)
import language.TaintTracking // Taint tracking (if needed)
import language.security.* // Security-specific predicates (if available)predicate isVulnerablePattern(Expr expr) {
// Define specific conditions that indicate vulnerability
expr instanceof SomeVulnerableExpr and
not expr.hasSecurityMitigation()
}class VulnerableDataFlow extends DataFlow::Configuration {
VulnerableDataFlow() { this = "VulnerableDataFlow" }
override predicate isSource(DataFlow::Node source) {
// Define sources of untrusted data
}
override predicate isSink(DataFlow::Node sink) {
// Define dangerous sinks
}
}- Use specific types: Prefer
MethodCalloverExprwhen possible - Early filtering: Apply most restrictive conditions first
- Leverage indices: Use built-in predicates that are optimized
- Avoid complex joins: Break down complex conditions into helper predicates
- Profile queries: Use
codeql query runwith performance metrics
- Over-broad matching: Ensure predicates are specific enough
- Missing edge cases: Consider inheritance, overloading, etc.
- Performance issues: Watch for cartesian products in joins
- False positives: Test against real-world codebases
- Ignoring data flow: Many vulnerabilities require tracking data flow
- Check import statements and library dependencies
- Verify predicate signatures match usage
- Ensure proper scoping of variables
- Use
selectstatements to inspect intermediate results - Break complex predicates into smaller, testable parts
- Add debug predicates to understand data flow
- Add
pragma[inline]to small, frequently-used predicates - Use
pragma[noinline]for large predicates to control optimization - Consider using
pragma[nomagic]to prevent unwanted joins
Essential commands for query development:
- qlt query generate new-query - Generate scaffolding for a new CodeQL query with packs and tests
- codeql query compile - Compile and validate query syntax
- codeql query run - Execute queries against databases
- codeql execute query-server2 - Run a persistent query execution server for efficient multi-query workflows and IDE integrations
- codeql query format - Format query source code
- codeql test run - Execute query test suites
- codeql test extract - Create test databases
- codeql database create - Create CodeQL databases
- codeql database analyze - Run queries against databases
- codeql pack install - Install query dependencies
- codeql resolve library-path - Resolve library paths
- codeql bqrs decode - Convert binary results to text
- codeql bqrs info - Inspect result metadata
- Test-Driven QL Development - Comprehensive TDD workflow
- Language-specific prompts - Additional guidance for specific languages