diff --git a/server/src/prompts/data-extension-development.prompt.md b/server/src/prompts/data-extension-development.prompt.md index 01a6fbf3..600e10cb 100644 --- a/server/src/prompts/data-extension-development.prompt.md +++ b/server/src/prompts/data-extension-development.prompt.md @@ -132,6 +132,8 @@ Validate the model against a real database: - If the `.model.yml` lives under `.github/codeql/extensions/` of the consuming repo, you are **done** — Code Scanning will load it on the next analysis. - If you authored a reusable model pack and want it to apply across an organization, publish it to GHCR with `codeql pack publish` and configure it under org Code security → Global settings → CodeQL analysis → Model packs. +> **When data extensions aren't enough**: If `subtypes: True` fails to match subclasses (common when the base type is a library stub not present in the database), or the detection logic cannot be expressed as a source/sink/summary tuple, a QL library change (`.qll`) is needed instead. Use the `codeql://prompts/ql-tdd-basic` workflow to develop and test the fix, then contribute it upstream to `github/codeql`. + ## Validation Checklist - [ ] Correct tuple format for the language (API Graph vs MaD) @@ -147,3 +149,13 @@ Validate the model against a real database: - `codeql://languages/{{language}}/library-modeling` — Language-specific library modeling guide - `codeql://templates/security` — Security query templates - `codeql://learning/test-driven-development` — TDD workflow for CodeQL queries + +## Troubleshooting + +| Issue | Likely Cause | Resolution | +| ----- | ------------ | ---------- | +| Extension not found by `codeql query run` | `.github/codeql/extensions/` is only auto-loaded by Code Scanning (GitHub Actions), not the CLI | Move `.model.yml` into the pack's `ext/` directory (e.g., `csharp/ql/lib/ext/`) or pass the directory via `--additional-packs` | +| Stale results after adding/changing `.model.yml` | Compilation cache is returning previously cached results | Use `--no-default-compilation-cache` with a fresh `--compilation-cache=` to force recompilation | +| `subtypes: True` not matching subclass methods | The base type only exists as a library stub in the database, not as extracted source | `subtypes` resolution requires the declaring type to be in the database. For framework base types (e.g., `PageModel`, `ControllerBase`) that are only stubs, use a QL-based source/sink class instead of a data extension | +| Extension loads but produces no findings | Missing link in the source → summary → sink chain | Verify all hops are modeled — a single missing `summaryModel` between source and sink will break the chain | +| YAML parse error or silent failure | Wrong column count for the extensible predicate | Double-check the exact column count for your language's format (MaD vs API Graph) — extra or missing columns fail silently | diff --git a/server/src/prompts/ql-tdd-basic.prompt.md b/server/src/prompts/ql-tdd-basic.prompt.md index 44c909f1..8b7be49e 100644 --- a/server/src/prompts/ql-tdd-basic.prompt.md +++ b/server/src/prompts/ql-tdd-basic.prompt.md @@ -214,6 +214,7 @@ codeql_test_accept: { - ❌ Not using #codeql_lsp_completion to discover available types - ❌ Not setting `workspace_uri` when using LSP tools (completions will be empty) - ❌ Creating tests that are too complex +- ❌ Not clearing compilation cache after adding data extensions (stale cached results hide new models) - ❌ Ignoring false positives in results - ❌ Not refactoring after tests pass diff --git a/server/src/resources/languages/csharp_library_modeling.md b/server/src/resources/languages/csharp_library_modeling.md index f62ac567..95863949 100644 --- a/server/src/resources/languages/csharp_library_modeling.md +++ b/server/src/resources/languages/csharp_library_modeling.md @@ -58,6 +58,13 @@ C# uses a **MaD (Models as Data)** format with **9–10 column tuples** that ide | `kind` | Source/sink/summary kind | `"sql-injection"`, `"taint"` | | `provenance` | Origin of the model | `"manual"` | +### Important: `subtypes` Flag + +- `True` — the model applies to the method **and all overrides** in subclasses and implementing classes +- `False` — only applies to the exact class specified + +> **Caveat**: `subtypes: True` requires the base type to be **present in the CodeQL database** as extracted source or a resolved reference. For framework base types that exist only as library stubs (e.g., `Microsoft.AspNetCore.Mvc.RazorPages.PageModel`), subtypes resolution may silently fail to match subclass methods. In these cases, model each concrete class explicitly or implement a QL-based source/sink class instead. + ### Important: C#-Specific Signature Rules - Type names must be **fully qualified**: `System.String`, not `string` diff --git a/server/src/tools/codeql/bqrs-decode.ts b/server/src/tools/codeql/bqrs-decode.ts index 568c6a24..2e406c00 100644 --- a/server/src/tools/codeql/bqrs-decode.ts +++ b/server/src/tools/codeql/bqrs-decode.ts @@ -23,7 +23,7 @@ export const codeqlBqrsDecodeTool: CLIToolDefinition = { command: 'codeql', subcommand: 'bqrs decode', inputSchema: { - files: z.array(z.string()).describe('BQRS file(s) to decode'), + files: z.array(z.string()).describe('Array of BQRS file paths to decode. Pass an array even for a single file, e.g. ["/path/to/results.bqrs"]'), output: createCodeQLSchemas.output(), format: z.enum(['csv', 'json', 'text', 'bqrs']).optional() .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'), diff --git a/server/src/tools/codeql/quick-evaluate.ts b/server/src/tools/codeql/quick-evaluate.ts index 5d908b44..c5c69c5d 100644 --- a/server/src/tools/codeql/quick-evaluate.ts +++ b/server/src/tools/codeql/quick-evaluate.ts @@ -60,7 +60,10 @@ export async function quickEvaluate({ export function registerQuickEvaluateTool(server: McpServer): void { server.tool( 'quick_evaluate', - 'Quick evaluate either a class or a predicate in a CodeQL query for debugging', + 'Resolve a class or predicate symbol in a CodeQL query file for quick evaluation. ' + + 'Locates the symbol position and returns an output path for results. ' + + 'Note: this tool validates the symbol exists but does not yet execute the evaluation — ' + + 'use codeql_query_run for full evaluation.', { file: z.string().describe('Path to the .ql file containing the symbol'), db: z.string().describe('Path to the CodeQL database'), diff --git a/server/src/tools/codeql/register-database.ts b/server/src/tools/codeql/register-database.ts index 018783f8..7a2fd4e0 100644 --- a/server/src/tools/codeql/register-database.ts +++ b/server/src/tools/codeql/register-database.ts @@ -90,7 +90,9 @@ export async function registerDatabase(dbPath: string): Promise { export function registerRegisterDatabaseTool(server: McpServer): void { server.tool( 'register_database', - 'Register a CodeQL database given a local path to the database directory', + 'Register a CodeQL database for use by other MCP tools. ' + + 'Validates that the database directory exists, contains codeql-database.yml, and has source files (src.zip or src/). ' + + 'Does not persist any session state — acts as a preflight check before using other database tools.', { db_path: z.string().describe('Path to the CodeQL database directory'), },