From d9b2f0f280bed7c2ec2edd1753eae5aa8f95698d Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 10 Jun 2026 15:03:30 -0300 Subject: [PATCH 1/6] feat(engine): detector precision, monorepo discovery, strict CLI with CI gate - XML_XXE now fires only on explicitly insecure entity configuration (the old lazy-dot lookahead matched every XML parser mention, including the entity-free browser DOMParser); precision corpus extended with safe/insecure XXE pairs - scanner discovers config/dep/BaaS files recursively (monorepo-aware), runs one parallel glob walk per category, /-normalizes paths, and detects frameworks from ALL workspace manifests - CLI: strict parseArgs (mistyped flags abort instead of silently changing the audit), --version, and a --fail-on CI gate - tools: --tool-timeout and --semgrep-config (local rules, metrics off); timeouts are reported as timeouts, not generic unavailability - consolidation: single sanitizeAgentName module (was 3 copies), shared extension/language maps (fixes *.pyw missing Python rules), single content split per file in the detector Co-Authored-By: Claude Fable 5 --- csreview/src/agentName.js | 23 + csreview/src/cli.js | 95 ++-- csreview/src/cliArgs.js | 128 ++++++ csreview/src/detector.js | 59 ++- csreview/src/dumpGuide.js | 11 +- csreview/src/index.js | 175 +++----- csreview/src/languages.js | 150 +++++++ csreview/src/localDast.js | 12 +- csreview/src/scanner.js | 547 +++++++++-------------- csreview/test/agent-name.test.js | 23 + csreview/test/cli-args.test.js | 61 +++ csreview/test/detector-precision.test.js | 69 +++ csreview/test/languages.test.js | 43 ++ csreview/test/scanner.test.js | 65 +++ csreview/test/tool-env.test.js | 36 ++ 15 files changed, 952 insertions(+), 545 deletions(-) create mode 100644 csreview/src/agentName.js create mode 100644 csreview/src/cliArgs.js create mode 100644 csreview/src/languages.js create mode 100644 csreview/test/agent-name.test.js create mode 100644 csreview/test/cli-args.test.js create mode 100644 csreview/test/languages.test.js create mode 100644 csreview/test/scanner.test.js diff --git a/csreview/src/agentName.js b/csreview/src/agentName.js new file mode 100644 index 0000000..eabdcf9 --- /dev/null +++ b/csreview/src/agentName.js @@ -0,0 +1,23 @@ +// @ts-check + +/** + * Canonical agent-name sanitizer for report file prefixes + * (`_security-report.html`, `_local-dast-report.html`, + * `_db-dump-guide.html`). + * + * This is the single source of truth: it used to exist as three separate + * copies (index.js, localDast.js, dumpGuide.js), and any drift between them + * would scatter one agent's reports across different file prefixes. + * + * @param {string} [agentName] + * @returns {string} lowercase `[a-z0-9_-]` name, never empty (falls back to "codex") + */ +export function sanitizeAgentName(agentName) { + const normalized = String(agentName || 'codex') + .trim() + .toLowerCase() + .replace(/[^a-z0-9_-]+/g, '-') + .replace(/-+/g, '-') + .replace(/^-|-$/g, ''); + return normalized || 'codex'; +} diff --git a/csreview/src/cli.js b/csreview/src/cli.js index 6acf8c9..3d1ab4a 100644 --- a/csreview/src/cli.js +++ b/csreview/src/cli.js @@ -11,9 +11,21 @@ import { generateDumpGuide, sanitizeAgentName } from './dumpGuide.js'; import { checkForUpdate } from './updateCheck.js'; import { checkToolFreshness } from './toolFreshness.js'; import { makeSecurityToolGatherer } from './provisionRuntime.js'; +import { parseCliArgs, countFindingsAtOrAbove } from './cliArgs.js'; const args = process.argv.slice(2); +// Strict parsing: an unknown or mistyped flag is a hard error (a silently +// ignored `--basline` would run the scan without the baseline and "pass"). +let cli; +try { + cli = parseCliArgs(args); +} catch (err) { + console.error(chalk.red(`\n Error: ${err.message}`)); + console.error(chalk.gray(' Run csreview --help for the supported options.\n')); + process.exit(1); +} + /** Read the installed CSReview version from package.json (best-effort). */ function readCurrentVersion() { try { @@ -29,7 +41,7 @@ function readCurrentVersion() { * reviews the change before updating. Skipped with --no-update-check. */ async function runUpdatePreflight() { - if (args.includes('--no-update-check')) return; + if (cli.noUpdateCheck) return; try { const result = await checkForUpdate(readCurrentVersion(), { timeoutMs: 4000 }); if (result.checked && result.updateAvailable) { @@ -77,9 +89,13 @@ async function runToolFreshness(tools) { } } -if (args.includes('--doctor')) { - const targetArg = args.find((arg) => !arg.startsWith('-')); - const targetDir = resolve(targetArg || '.'); +if (cli.version) { + console.log(readCurrentVersion() || 'unknown'); + process.exit(0); +} + +if (cli.doctor) { + const targetDir = resolve(cli.targetArg || '.'); const tools = await checkExternalTools(targetDir); console.log(chalk.bold.cyan('\n CSReview Tool Doctor\n')); @@ -98,7 +114,7 @@ if (args.includes('--doctor')) { console.log(` ${name.padEnd(12)} ${status} (${requirement}) - ${detail}`); } - if (!args.includes('--no-tool-check')) { + if (!cli.noToolCheck) { await runToolFreshness(tools); } @@ -107,7 +123,7 @@ if (args.includes('--doctor')) { process.exit(0); } -if (args.includes('--help') || args.includes('-h') || args.length === 0) { +if (cli.help || args.length === 0) { console.log(` ${chalk.bold.cyan('CSReview')} - Development-time local workspace security alignment for AI coding agents @@ -118,6 +134,7 @@ ${chalk.bold('USAGE:')} ${chalk.bold('OPTIONS:')} --output, -o Output directory for reports (default: /csreview-reports/) --agent-name Prefix report files with the coding agent name (default: codex) + --fail-on Exit 1 when findings at or above this level remain (critical|high|medium|low) - CI gate --local-dast-url Run complementary local-only DAST against localhost/127.0.0.1 --confirm-local-dast Required confirmation flag for --local-dast-url --strict-partials Fail when csreview-reports/.partials/ does not reconcile @@ -125,15 +142,22 @@ ${chalk.bold('OPTIONS:')} --update-baseline Write/refresh the baseline file from this run (with --baseline or default .csreview-baseline.json) --dump-guide Also generate a read-only per-backend local DB dump guide (auto with --local-dast-url) --provision-tools Opt-in: run stack-native security tools (Gitleaks/Trivy/Bandit/gosec) and, if missing, download them from OFFICIAL sources (SHA-256 verified) into an isolated, gitignored .csreview/bin/. Higher fidelity, fewer false positives. + --tool-timeout Per-tool timeout in seconds for Semgrep/audits/OSV (default: 120) + --semgrep-config Semgrep config to use instead of "auto" (local rules path or registry ref; enables offline scans) --no-update-check Skip the pre-flight CSReview self-update check --doctor Check external security tools (and their freshness) without scanning source code + --version, -v Print the installed CSReview version --help, -h Show this help message + Unknown flags are an error (strict parsing): a mistyped option aborts the scan + instead of silently changing what is audited. + ${chalk.bold('EXAMPLES:')} csreview . csreview /path/to/project csreview . --output ./security-reports csreview . --agent-name claude + csreview . --fail-on high # CI: exit 1 if HIGH/CRITICAL findings remain csreview . --local-dast-url http://localhost:3000 --confirm-local-dast csreview --doctor . @@ -162,37 +186,22 @@ ${chalk.bold('SECURITY TOOLS:')} process.exit(0); } -const targetDir = resolve(args[0]); -let outputDir = null; -let agentName = process.env.CSREVIEW_AGENT_NAME || 'codex'; -let localDastUrl = null; -const strictPartials = args.includes('--strict-partials'); - -const outputIdx = args.findIndex((a) => a === '--output' || a === '-o'); -if (outputIdx !== -1 && args[outputIdx + 1]) { - outputDir = resolve(args[outputIdx + 1]); -} - -const agentNameIdx = args.findIndex((a) => a === '--agent-name'); -if (agentNameIdx !== -1 && args[agentNameIdx + 1]) { - agentName = args[agentNameIdx + 1]; +if (!cli.targetArg) { + console.error(chalk.red('\n Error: missing . Run csreview --help for usage.\n')); + process.exit(1); } -const localDastIdx = args.findIndex((a) => a === '--local-dast-url'); -if (localDastIdx !== -1 && args[localDastIdx + 1]) { - localDastUrl = args[localDastIdx + 1]; -} -const localDastConfirmed = args.includes('--confirm-local-dast'); +const targetDir = resolve(cli.targetArg); +const outputDir = cli.output ? resolve(cli.output) : null; +const agentName = cli.agentName || process.env.CSREVIEW_AGENT_NAME || 'codex'; +const localDastUrl = cli.localDastUrl; +const localDastConfirmed = cli.confirmLocalDast; +const strictPartials = cli.strictPartials; -let baselinePath = null; -const baselineIdx = args.findIndex((a) => a === '--baseline'); -if (baselineIdx !== -1 && args[baselineIdx + 1] && !args[baselineIdx + 1].startsWith('-')) { - baselinePath = resolve(args[baselineIdx + 1]); -} -const updateBaseline = args.includes('--update-baseline'); -const updateBaselinePath = updateBaseline ? baselinePath || resolve(targetDir, DEFAULT_BASELINE_FILE) : null; +const baselinePath = cli.baseline ? resolve(cli.baseline) : null; +const updateBaselinePath = cli.updateBaseline ? baselinePath || resolve(targetDir, DEFAULT_BASELINE_FILE) : null; -const provisionTools = args.includes('--provision-tools'); +const provisionTools = cli.provisionTools; if (!existsSync(targetDir)) { console.error(chalk.red(`\n Error: Directory not found: ${targetDir}\n`)); @@ -236,6 +245,8 @@ try { strictPartials, baselinePath, updateBaselinePath, + toolTimeoutMs: cli.toolTimeoutMs || undefined, + semgrepConfig: cli.semgrepConfig || undefined, gatherSecurityTools: securityToolGatherer, }); @@ -340,7 +351,7 @@ try { // Phase 9 helper: a read-only per-backend "safe local dump" guide so the user // can prepare an isolated local copy before any optional local DAST. - const wantDumpGuide = args.includes('--dump-guide') || Boolean(localDastUrl); + const wantDumpGuide = cli.dumpGuide || Boolean(localDastUrl); if (wantDumpGuide) { try { const projectInfo = await scanProject(targetDir); @@ -393,6 +404,22 @@ try { } console.log(''); + + // CI gate: with --fail-on , exit non-zero when the report contains + // findings at or above that level, so a pipeline can block the merge. Reports + // are always written first — the gate only changes the exit code. + if (cli.failOn) { + const gated = countFindingsAtOrAbove(result.severityCounts, cli.failOn); + if (gated > 0) { + console.error( + chalk.red.bold( + ` Failing: ${gated} finding(s) at or above ${cli.failOn} (--fail-on ${cli.failOn.toLowerCase()}).\n`, + ), + ); + process.exit(1); + } + console.log(chalk.green(` Gate passed: no findings at or above ${cli.failOn} (--fail-on).\n`)); + } } catch (err) { console.error(chalk.red(`\n Fatal Error: ${err.message}\n`)); if (process.env.DEBUG) console.error(err.stack); diff --git a/csreview/src/cliArgs.js b/csreview/src/cliArgs.js new file mode 100644 index 0000000..5b39a80 --- /dev/null +++ b/csreview/src/cliArgs.js @@ -0,0 +1,128 @@ +// @ts-check +import { parseArgs } from 'util'; + +/** + * Strict CLI argument parsing. + * + * The CLI is a security gate, so a mistyped flag must be a hard error — the + * previous hand-rolled `findIndex` parsing silently ignored unknown flags, + * meaning `--basline known.json` ran a full scan WITHOUT the baseline and + * reported success. `node:util` parseArgs in strict mode turns that into an + * immediate, explanatory failure. + */ + +const CLI_OPTIONS = /** @type {const} */ ({ + output: { type: 'string', short: 'o' }, + 'agent-name': { type: 'string' }, + 'local-dast-url': { type: 'string' }, + 'confirm-local-dast': { type: 'boolean', default: false }, + 'strict-partials': { type: 'boolean', default: false }, + baseline: { type: 'string' }, + 'update-baseline': { type: 'boolean', default: false }, + 'dump-guide': { type: 'boolean', default: false }, + 'provision-tools': { type: 'boolean', default: false }, + 'fail-on': { type: 'string' }, + 'tool-timeout': { type: 'string' }, + 'semgrep-config': { type: 'string' }, + 'no-update-check': { type: 'boolean', default: false }, + 'no-tool-check': { type: 'boolean', default: false }, + doctor: { type: 'boolean', default: false }, + help: { type: 'boolean', short: 'h', default: false }, + version: { type: 'boolean', short: 'v', default: false }, +}); + +/** Severities accepted by `--fail-on` (INFO is never a CI gate). */ +export const FAIL_ON_SEVERITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW']; + +const SEVERITY_RANK = { CRITICAL: 5, HIGH: 4, MEDIUM: 3, LOW: 2, INFO: 1 }; + +/** + * Validate and normalize a `--fail-on` value. Null/undefined means "no gate". + * + * @param {string} [value] + * @returns {string|null} + */ +export function normalizeFailOn(value) { + if (value === undefined || value === null || value === '') return null; + const upper = String(value).trim().toUpperCase(); + if (!FAIL_ON_SEVERITIES.includes(upper)) { + throw new Error(`--fail-on must be one of: ${FAIL_ON_SEVERITIES.join(', ').toLowerCase()} (got "${value}")`); + } + return upper; +} + +/** + * Count findings at or above the gate severity. + * + * @param {Record} severityCounts + * @param {string} failOn normalized severity (see {@link normalizeFailOn}) + * @returns {number} + */ +export function countFindingsAtOrAbove(severityCounts, failOn) { + const threshold = SEVERITY_RANK[failOn]; + if (!threshold) return 0; + let total = 0; + for (const [severity, count] of Object.entries(severityCounts || {})) { + if ((SEVERITY_RANK[severity] || 0) >= threshold) { + total += Number(count) || 0; + } + } + return total; +} + +/** + * Validate and normalize a `--tool-timeout` value (seconds) into milliseconds. + * + * @param {string} [value] + * @returns {number|null} + */ +export function normalizeToolTimeout(value) { + if (value === undefined || value === null || value === '') return null; + const seconds = Number(value); + if (!Number.isFinite(seconds) || seconds <= 0) { + throw new Error(`--tool-timeout must be a positive number of seconds (got "${value}")`); + } + return Math.round(seconds * 1000); +} + +/** + * Parse raw argv (without the node/script prefix) into a flat options object. + * Throws with a human-readable message on unknown flags, missing option + * values, or invalid `--fail-on` / `--tool-timeout` values. + * + * @param {string[]} argv + */ +export function parseCliArgs(argv) { + const parsed = parseArgs({ + args: argv, + options: /** @type {any} */ (CLI_OPTIONS), + allowPositionals: true, + strict: true, + }); + const values = /** @type {Record} */ (parsed.values); + const positionals = parsed.positionals; + + /** @param {string|boolean|undefined} value @returns {string|null} */ + const asString = (value) => (typeof value === 'string' && value !== '' ? value : null); + + return { + targetArg: positionals[0] || null, + output: asString(values.output), + agentName: asString(values['agent-name']), + localDastUrl: asString(values['local-dast-url']), + confirmLocalDast: Boolean(values['confirm-local-dast']), + strictPartials: Boolean(values['strict-partials']), + baseline: asString(values.baseline), + updateBaseline: Boolean(values['update-baseline']), + dumpGuide: Boolean(values['dump-guide']), + provisionTools: Boolean(values['provision-tools']), + failOn: normalizeFailOn(asString(values['fail-on']) ?? undefined), + toolTimeoutMs: normalizeToolTimeout(asString(values['tool-timeout']) ?? undefined), + semgrepConfig: asString(values['semgrep-config']), + noUpdateCheck: Boolean(values['no-update-check']), + noToolCheck: Boolean(values['no-tool-check']), + doctor: Boolean(values.doctor), + help: Boolean(values.help), + version: Boolean(values.version), + }; +} diff --git a/csreview/src/detector.js b/csreview/src/detector.js index dae3a22..2df10ca 100644 --- a/csreview/src/detector.js +++ b/csreview/src/detector.js @@ -1,6 +1,7 @@ // @ts-check import { readFileSafe } from './scanner.js'; import { safeResolveInside } from './pathSafety.js'; +import { getLanguage } from './languages.js'; const SEVERITY_ORDER = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3, INFO: 4 }; @@ -363,14 +364,17 @@ const VULNERABILITY_PATTERNS = [ severity: 'CRITICAL', category: 'Injection', name: 'XML External Entity (XXE)', - description: 'XML parsing without disabling external entities.', + description: 'XML parser explicitly configured to resolve external entities or load DTDs.', + // Only explicit insecure configuration. A negative lookahead placed after a + // lazy `.*?` is always satisfiable, so the previous pattern flagged EVERY + // parser mention (including the entity-free browser DOMParser) as CRITICAL. regex: - /(?:libxml|xml2js|DOMParser|XMLParser|SAXParser|lxml|etree).*?(?!.*(?:noent|nonet|dtdload|noDTDload|resolveEntities\s*[=:]\s*(?:false|0)))/gi, + /\bnoent\b\s*[:=]\s*true|\bLIBXML_(?:NOENT|DTDLOAD)\b|libxml_disable_entity_loader\s*\(\s*false|\b(?:resolve_entities|load_dtd)\s*=\s*true|setExpandEntityReferences\s*\(\s*true|external-(?:general|parameter)-entities['"]\s*,\s*true|disallow-doctype-decl['"]\s*,\s*false|DtdProcessing\.Parse|XmlResolver\s*=\s*new\s+XmlUrlResolver|ParseOptions::NOENT|Nokogiri[^\n]*\bnoent\b/gi, cwe: 'CWE-611', owasp: 'A05:2021-Security Misconfiguration', - fix: 'Disable external entity processing.', + fix: 'Keep external entity resolution disabled (noent: false, resolve_entities=False, DtdProcessing.Prohibit) or use a hardened parser such as defusedxml.', exploitation: 'Attacker submits XXE payload to read server files.', - confidence: 'MEDIUM', + confidence: 'HIGH', vibeRisk: false, references: ['https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html'], }, @@ -1349,29 +1353,6 @@ const CONFIG_MISCONFIG_PATTERNS = [ }, ]; -const LANGUAGE_MAP = { - '.js': 'javascript', - '.mjs': 'javascript', - '.cjs': 'javascript', - '.ts': 'typescript', - '.tsx': 'typescript', - '.py': 'python', - '.java': 'java', - '.go': 'go', - '.rs': 'rust', - '.php': 'php', - '.rb': 'ruby', - '.cs': 'csharp', - '.c': 'c', - '.cpp': 'cpp', - '.h': 'c', - '.hpp': 'cpp', - '.pas': 'delphi', - '.dpr': 'delphi', - '.lpr': 'delphi', - '.pp': 'delphi', -}; - const LANGUAGE_SPECIFIC_PATTERNS = { python: ['PY_DESERIALIZE', 'PY_SQL_INJECTION', 'PY_COMMAND_INJECTION', 'PY_REQUESTS_VERIFY'], csharp: ['CS_SQL_INJECTION', 'CS_DESERIALIZE', 'CS_XSS', 'CS_PATH_TRAVERSAL'], @@ -1531,9 +1512,9 @@ function snippetAroundMatch(line, match, maxLength = 2000) { return `${prefix}${text.slice(start, end)}${suffix}`; } -export function detectSecrets(content, filePath) { +export function detectSecrets(content, filePath, precomputedLines) { const findings = []; - const lines = content.split('\n'); + const lines = precomputedLines || content.split('\n'); for (const pattern of SECRET_PATTERNS) { for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) { @@ -1570,7 +1551,7 @@ export function detectSecrets(content, filePath) { return findings; } -function detectInContent(content, filePath, language, kind) { +function detectInContent(content, filePath, language, kind, precomputedLines) { const findings = []; const patterns = VULNERABILITY_PATTERNS.filter((pattern) => !LANGUAGE_SPECIFIC_PATTERN_IDS.has(pattern.id)); @@ -1589,7 +1570,7 @@ function detectInContent(content, filePath, language, kind) { patterns.push(...CONFIG_MISCONFIG_PATTERNS); } - const lines = content.split('\n'); + const lines = precomputedLines || content.split('\n'); for (const pattern of patterns) { for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) { @@ -1643,7 +1624,15 @@ export function detectVulnerabilities(projectInfo) { const ext = file.path.slice(file.path.lastIndexOf('.')).toLowerCase(); if (BINARY_EXTENSIONS.has(ext)) continue; - const language = file.language && file.language !== 'unknown' ? file.language : LANGUAGE_MAP[ext] || null; + // Fallback to the shared extension map so a caller that did not enrich + // `language` still gets the language-specific rule set (e.g. *.pyw). + const fallbackLanguage = getLanguage(file.path); + const language = + file.language && file.language !== 'unknown' + ? file.language + : fallbackLanguage !== 'unknown' + ? fallbackLanguage + : null; let content; let isMinified; @@ -1659,12 +1648,14 @@ export function detectVulnerabilities(projectInfo) { } if (!content || typeof content !== 'string') continue; - const secretFindings = detectSecrets(content, file.path); + // Split once per file; secrets and vulnerability passes share the lines. + const lines = content.split('\n'); + const secretFindings = detectSecrets(content, file.path, lines); allFindings.push(...secretFindings); if (isMinified) continue; - const vulnFindings = detectInContent(content, file.path, language, file.kind); + const vulnFindings = detectInContent(content, file.path, language, file.kind, lines); allFindings.push(...vulnFindings); } diff --git a/csreview/src/dumpGuide.js b/csreview/src/dumpGuide.js index 30d5add..c293874 100644 --- a/csreview/src/dumpGuide.js +++ b/csreview/src/dumpGuide.js @@ -6,6 +6,7 @@ import fs from 'fs'; import path from 'path'; import { safeResolveInside } from './pathSafety.js'; +import { sanitizeAgentName } from './agentName.js'; function escapeHtml(value) { return String(value ?? '') @@ -16,16 +17,6 @@ function escapeHtml(value) { .replace(/'/g, '''); } -function sanitizeAgentName(agentName) { - const normalized = String(agentName || 'codex') - .trim() - .toLowerCase() - .replace(/[^a-z0-9_-]+/g, '-') - .replace(/-+/g, '-') - .replace(/^-|-$/g, ''); - return normalized || 'codex'; -} - // fileBased: the database lives in a file. Finding that file in the repo/installer is // itself a data-exposure finding, flagged before any test. export const BACKENDS = [ diff --git a/csreview/src/index.js b/csreview/src/index.js index 7201234..dfad5da 100644 --- a/csreview/src/index.js +++ b/csreview/src/index.js @@ -18,6 +18,8 @@ import { DEFAULT_IGNORE_DIRS, } from './ignore.js'; import { loadBaseline, applyBaseline, writeBaseline } from './baseline.js'; +import { sanitizeAgentName } from './agentName.js'; +import { getLanguage } from './languages.js'; /** * Canonical finding object exchanged by the deterministic engine, tool @@ -155,71 +157,6 @@ export function validateWindowsCmdArgs(commandPath, args, platform = process.pla } } -const LANG_MAP = { - js: 'javascript', - mjs: 'javascript', - cjs: 'javascript', - ts: 'typescript', - tsx: 'typescript', - jsx: 'javascript', - py: 'python', - java: 'java', - kt: 'kotlin', - go: 'go', - rs: 'rust', - php: 'php', - rb: 'ruby', - cs: 'csharp', - swift: 'swift', - c: 'c', - h: 'c', - cpp: 'cpp', - cc: 'cpp', - cxx: 'cpp', - hpp: 'cpp', - pas: 'delphi', - dpr: 'delphi', - dpk: 'delphi', - lpr: 'delphi', - pp: 'delphi', - vue: 'vue', - svelte: 'svelte', - sh: 'bash', - bash: 'bash', - sql: 'sql', - graphql: 'graphql', - gql: 'graphql', - html: 'html', - htm: 'html', - xml: 'xml', - json: 'json', - yaml: 'yaml', - yml: 'yaml', - toml: 'toml', - env: 'env', - tf: 'terraform', - tfvars: 'terraform', - lua: 'lua', - r: 'r', - R: 'r', - scala: 'scala', - groovy: 'groovy', - ex: 'elixir', - exs: 'elixir', - erl: 'erlang', - hs: 'haskell', - dart: 'dart', - zig: 'zig', - nim: 'nim', - v: 'v', - sol: 'solidity', -}; - -function getLanguage(filePath) { - const ext = filePath.includes('.') ? filePath.split('.').pop().toLowerCase() : ''; - return LANG_MAP[ext] || 'unknown'; -} - function enrichFiles(projectInfo) { const configSet = new Set(projectInfo.configFiles || []); const baasSet = new Set(projectInfo.baasFiles || []); @@ -242,38 +179,26 @@ function formatDuration(ms) { return `${Math.floor(ms / 60000)}m ${Math.round((ms % 60000) / 1000)}s`; } -function sanitizeAgentName(agentName) { - const raw = String(agentName || 'codex') - .trim() - .toLowerCase(); - let normalized = ''; - let lastWasGeneratedHyphen = false; - - for (const char of raw) { - const code = char.charCodeAt(0); - const isSafeAscii = (code >= 97 && code <= 122) || (code >= 48 && code <= 57) || char === '_' || char === '-'; - - if (isSafeAscii) { - normalized += char; - lastWasGeneratedHyphen = false; - } else if (normalized && !lastWasGeneratedHyphen) { - normalized += '-'; - lastWasGeneratedHyphen = true; - } - } - - let start = 0; - let end = normalized.length; - while (start < end && normalized[start] === '-') start += 1; - while (end > start && normalized[end - 1] === '-') end -= 1; +// Default per-tool execution budget. Large repos can exceed it — in that case +// the scan silently degraded to "unavailable" with a generic message, so the +// timeout branch below names the cause and the knob that raises it. +const DEFAULT_TOOL_TIMEOUT_MS = 120000; - return normalized.slice(start, end) || 'codex'; -} - -function toolErrorMessage(command, err) { +/** + * Human-readable failure reason for an external tool run. + * + * @param {string} command + * @param {{code?: string, killed?: boolean, signal?: string, message?: string}} err + * @param {number} [timeoutMs] the timeout the tool ran under, for the message + */ +export function toolErrorMessage(command, err, timeoutMs) { if (err?.code === 'ENOENT') { return `${command} not found in PATH`; } + if (err?.killed && (err?.signal === 'SIGTERM' || err?.signal === 'SIGKILL')) { + const seconds = Math.round((timeoutMs || DEFAULT_TOOL_TIMEOUT_MS) / 1000); + return `${command} timed out after ${seconds}s; raise it with --tool-timeout or narrow the scan scope`; + } if (err?.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER' || /maxBuffer/i.test(err?.message || '')) { return `${command} output exceeded maxBuffer; rerun with a narrower scope or inspect the tool output directly`; } @@ -885,18 +810,35 @@ export function semgrepExcludeArgs(dirs = DEFAULT_IGNORE_DIRS) { return dirs.flatMap((dir) => ['--exclude', dir]); } -async function runSemgrep(rootDir) { +/** + * Build the Semgrep scan argument list. `--config auto` (the default) pulls + * rules from the registry and REQUIRES metrics, so they stay on; any other + * config (a local rules path or explicit registry ref) is run with + * `--metrics=off`, which is what makes air-gapped/private scans possible. + * + * @param {string} rootDir + * @param {{config?: string}} [options] + * @returns {string[]} + */ +export function buildSemgrepArgs(rootDir, options = {}) { + const config = options.config || 'auto'; + const args = ['--config', config, '--json', '--quiet', ...semgrepExcludeArgs()]; + if (config !== 'auto') { + args.push('--metrics=off'); + } + args.push(rootDir); + return args; +} + +async function runSemgrep(rootDir, options = {}) { + const timeoutMs = options.timeoutMs || DEFAULT_TOOL_TIMEOUT_MS; try { const versionResult = await execTool('semgrep', ['--version'], { timeout: VERSION_CHECK_TIMEOUT_MS }); - const scanResult = await execTool( - 'semgrep', - ['--config', 'auto', '--json', '--quiet', ...semgrepExcludeArgs(), rootDir], - { - cwd: rootDir, - timeout: 120000, - maxBuffer: 20 * 1024 * 1024, - }, - ); + const scanResult = await execTool('semgrep', buildSemgrepArgs(rootDir, { config: options.config }), { + cwd: rootDir, + timeout: timeoutMs, + maxBuffer: 20 * 1024 * 1024, + }); const parsed = JSON.parse(scanResult.stdout || '{}'); return { available: true, @@ -911,7 +853,7 @@ async function runSemgrep(rootDir) { available: false, required: true, version: null, - error: toolErrorMessage('semgrep', err), + error: toolErrorMessage('semgrep', err, timeoutMs), findings: [], rawCount: 0, }; @@ -1007,7 +949,8 @@ export function detectNodeAuditStrategy(rootDir) { }; } -async function runPackageAudit(rootDir) { +async function runPackageAudit(rootDir, options = {}) { + const timeoutMs = options.timeoutMs || DEFAULT_TOOL_TIMEOUT_MS; const strategy = detectNodeAuditStrategy(rootDir); if (strategy.skipped) { return { @@ -1029,7 +972,7 @@ async function runPackageAudit(rootDir) { try { const auditResult = await execTool(strategy.command, strategy.args, { cwd: rootDir, - timeout: 120000, + timeout: timeoutMs, maxBuffer: 20 * 1024 * 1024, }); stdout = auditResult.stdout; @@ -1065,21 +1008,22 @@ async function runPackageAudit(rootDir) { manager: strategy.manager, lockfile: strategy.lockfile, version: null, - error: toolErrorMessage(strategy.label || strategy.command, err), + error: toolErrorMessage(strategy.label || strategy.command, err, timeoutMs), findings: [], rawCount: 0, }; } } -async function runOsvScanner(rootDir) { +async function runOsvScanner(rootDir, options = {}) { + const timeoutMs = options.timeoutMs || DEFAULT_TOOL_TIMEOUT_MS; try { const versionResult = await execTool('osv-scanner', ['--version'], { timeout: 30000 }); let stdout = ''; try { const scanResult = await execTool('osv-scanner', ['scan', '--format', 'json', rootDir], { cwd: rootDir, - timeout: 120000, + timeout: timeoutMs, maxBuffer: 20 * 1024 * 1024, }); stdout = scanResult.stdout; @@ -1102,7 +1046,7 @@ async function runOsvScanner(rootDir) { available: false, required: false, version: null, - error: toolErrorMessage('osv-scanner', err), + error: toolErrorMessage('osv-scanner', err, timeoutMs), findings: [], rawCount: 0, }; @@ -1160,7 +1104,7 @@ export async function checkExternalTools(rootDir = process.cwd()) { * Run engine-orchestrated external tools once and return their normalized output. * * @param {string} rootDir - * @param {{runTools?: boolean}} options + * @param {{runTools?: boolean, toolTimeoutMs?: number, semgrepConfig?: string}} options * @returns {Promise} */ async function runSecurityTools(rootDir, options) { @@ -1168,10 +1112,11 @@ async function runSecurityTools(rootDir, options) { return createSkippedToolResult('Tool execution disabled by caller.'); } + const timeoutMs = options.toolTimeoutMs || DEFAULT_TOOL_TIMEOUT_MS; const [semgrep, packageAudit, osvScanner] = await Promise.all([ - runSemgrep(rootDir), - runPackageAudit(rootDir), - runOsvScanner(rootDir), + runSemgrep(rootDir, { timeoutMs, config: options.semgrepConfig }), + runPackageAudit(rootDir, { timeoutMs }), + runOsvScanner(rootDir, { timeoutMs }), ]); return { mode: classifyToolMode({ semgrep, packageAudit, npmAudit: packageAudit, osvScanner }), @@ -1210,7 +1155,7 @@ export function classifyToolMode(toolResults = {}) { * Run a full CSReview static analysis and write reports. * * @param {string} rootDir - * @param {{outputDir?: string, agentName?: string, runTools?: boolean, strictPartials?: boolean, htmlReportPath?: string, markdownReportPath?: string, baselinePath?: string, updateBaselinePath?: string, gatherSecurityTools?: (projectInfo: object, rootDir: string) => Promise<{findings?: Array, results?: Array}>}} [options] + * @param {{outputDir?: string, agentName?: string, runTools?: boolean, strictPartials?: boolean, htmlReportPath?: string, markdownReportPath?: string, baselinePath?: string, updateBaselinePath?: string, toolTimeoutMs?: number, semgrepConfig?: string, gatherSecurityTools?: (projectInfo: object, rootDir: string) => Promise<{findings?: Array, results?: Array}>}} [options] */ export async function runAnalysis(rootDir, options = {}) { const startTime = Date.now(); diff --git a/csreview/src/languages.js b/csreview/src/languages.js new file mode 100644 index 0000000..feb49dc --- /dev/null +++ b/csreview/src/languages.js @@ -0,0 +1,150 @@ +// @ts-check + +/** + * Single source of truth for file-extension metadata. + * + * Extension→language (detector rule scoping, report metadata) and + * extension→tech-stack-label (project overview) used to live in three + * divergent maps across index.js, detector.js, and scanner.js — the detector + * copy was stale enough that `.pyw` files never received the Python-specific + * rules. Both maps live here so adding an extension updates every consumer. + */ + +/** Bare extension (no dot) → canonical language id. */ +export const LANG_MAP = { + js: 'javascript', + mjs: 'javascript', + cjs: 'javascript', + ts: 'typescript', + tsx: 'typescript', + jsx: 'javascript', + py: 'python', + pyw: 'python', + java: 'java', + kt: 'kotlin', + kts: 'kotlin', + go: 'go', + rs: 'rust', + php: 'php', + phtml: 'php', + rb: 'ruby', + erb: 'ruby', + cs: 'csharp', + swift: 'swift', + c: 'c', + h: 'c', + cpp: 'cpp', + cc: 'cpp', + cxx: 'cpp', + hpp: 'cpp', + pas: 'delphi', + dpr: 'delphi', + dpk: 'delphi', + lpr: 'delphi', + pp: 'delphi', + vue: 'vue', + svelte: 'svelte', + sh: 'bash', + bash: 'bash', + sql: 'sql', + graphql: 'graphql', + gql: 'graphql', + html: 'html', + htm: 'html', + xml: 'xml', + json: 'json', + yaml: 'yaml', + yml: 'yaml', + toml: 'toml', + env: 'env', + tf: 'terraform', + tfvars: 'terraform', + lua: 'lua', + r: 'r', + scala: 'scala', + groovy: 'groovy', + ex: 'elixir', + exs: 'elixir', + erl: 'erlang', + hs: 'haskell', + dart: 'dart', + zig: 'zig', + nim: 'nim', + v: 'v', + sol: 'solidity', +}; + +/** Bare extension (no dot) → human-readable tech-stack label. */ +export const EXTENSION_TO_TECH = { + js: 'JavaScript/TypeScript', + mjs: 'JavaScript/TypeScript', + cjs: 'JavaScript/TypeScript', + ts: 'JavaScript/TypeScript', + tsx: 'JavaScript/TypeScript', + jsx: 'JavaScript/TypeScript', + py: 'Python', + pyw: 'Python', + java: 'Java', + kt: 'Kotlin', + kts: 'Kotlin', + go: 'Go', + rs: 'Rust', + php: 'PHP', + phtml: 'PHP', + rb: 'Ruby', + erb: 'Ruby', + cs: 'C#', + cshtml: 'C#', + razor: 'C#', + c: 'C/C++', + cpp: 'C/C++', + cc: 'C/C++', + cxx: 'C/C++', + h: 'C/C++', + hpp: 'C/C++', + swift: 'Swift', + dart: 'Dart', + pas: 'Delphi', + pp: 'Delphi', + dpr: 'Delphi', + lpr: 'Delphi', + lfm: 'Delphi', + dfm: 'Delphi', + lua: 'Lua', + scala: 'Scala', + sc: 'Scala', + ex: 'Elixir', + exs: 'Elixir', + clj: 'Clojure', + cljs: 'Clojure', + vue: 'Vue', + svelte: 'Svelte', + html: 'HTML', + htm: 'HTML', + ejs: 'HTML Templates', + hbs: 'HTML Templates', + twig: 'HTML Templates', + pug: 'HTML Templates', + jade: 'HTML Templates', + sh: 'Shell', + bash: 'Shell', + zsh: 'Shell', + ps1: 'Shell', + bat: 'Shell', + cmd: 'Shell', + sql: 'SQL', + graphql: 'GraphQL', + gql: 'GraphQL', +}; + +/** + * Resolve a file path to its canonical language id ('unknown' when unmapped). + * + * @param {string} filePath + * @returns {string} + */ +export function getLanguage(filePath) { + const name = String(filePath || ''); + const ext = name.includes('.') ? name.split('.').pop().toLowerCase() : ''; + return LANG_MAP[ext] || 'unknown'; +} diff --git a/csreview/src/localDast.js b/csreview/src/localDast.js index 28f76bf..0b370b0 100644 --- a/csreview/src/localDast.js +++ b/csreview/src/localDast.js @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import { normalizeLocalPath, safeResolveInside } from './pathSafety.js'; +import { sanitizeAgentName } from './agentName.js'; // Node's URL parser returns the bracketed form for IPv6 loopback (e.g. new URL('http://[::1]').hostname === '[::1]'). const LOCAL_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']); @@ -14,17 +15,6 @@ const SECURITY_HEADERS = [ 'permissions-policy', ]; -function sanitizeAgentName(agentName) { - const raw = String(agentName || 'codex') - .trim() - .toLowerCase(); - const normalized = raw - .replace(/[^a-z0-9_-]+/g, '-') - .replace(/-+/g, '-') - .replace(/^-|-$/g, ''); - return normalized || 'codex'; -} - function escapeHtml(value) { return String(value ?? '') .replace(/&/g, '&') diff --git a/csreview/src/scanner.js b/csreview/src/scanner.js index 9ee4458..ecbbf6d 100644 --- a/csreview/src/scanner.js +++ b/csreview/src/scanner.js @@ -4,6 +4,7 @@ import path from 'path'; import { glob } from 'glob'; import { safeResolveInside } from './pathSafety.js'; import { buildScannerIgnoreGlobs } from './ignore.js'; +import { EXTENSION_TO_TECH } from './languages.js'; const SOURCE_EXTENSIONS = [ 'js', @@ -73,72 +74,37 @@ const SOURCE_EXTENSIONS = [ // both paths. Keep ignore.js side-effect-free so this top-level call is safe. const IGNORE_PATTERNS = buildScannerIgnoreGlobs(); -const EXTENSION_TO_TECH = { - js: 'JavaScript/TypeScript', - mjs: 'JavaScript/TypeScript', - cjs: 'JavaScript/TypeScript', - ts: 'JavaScript/TypeScript', - tsx: 'JavaScript/TypeScript', - jsx: 'JavaScript/TypeScript', - py: 'Python', - pyw: 'Python', - java: 'Java', - kt: 'Kotlin', - kts: 'Kotlin', - go: 'Go', - rs: 'Rust', - php: 'PHP', - phtml: 'PHP', - rb: 'Ruby', - erb: 'Ruby', - cs: 'C#', - cshtml: 'C#', - razor: 'C#', - c: 'C/C++', - cpp: 'C/C++', - cc: 'C/C++', - cxx: 'C/C++', - h: 'C/C++', - hpp: 'C/C++', - swift: 'Swift', - dart: 'Dart', - pas: 'Delphi', - pp: 'Delphi', - dpr: 'Delphi', - lpr: 'Delphi', - lfm: 'Delphi', - dfm: 'Delphi', - lua: 'Lua', - scala: 'Scala', - sc: 'Scala', - ex: 'Elixir', - exs: 'Elixir', - clj: 'Clojure', - cljs: 'Clojure', - vue: 'Vue', - svelte: 'Svelte', - html: 'HTML', - htm: 'HTML', - ejs: 'HTML Templates', - hbs: 'HTML Templates', - twig: 'HTML Templates', - pug: 'HTML Templates', - jade: 'HTML Templates', - sh: 'Shell', - bash: 'Shell', - zsh: 'Shell', - ps1: 'Shell', - bat: 'Shell', - cmd: 'Shell', - sql: 'SQL', - graphql: 'GraphQL', - gql: 'GraphQL', -}; - function buildSourceGlobPattern() { return `**/*.{${SOURCE_EXTENSIONS.join(',')}}`; } +// Discovery patterns match at ANY depth (`**/` prefix): monorepos keep configs, +// manifests, and BaaS rules inside nested workspaces (apps/*, services/*, +// packages/*), and IGNORE_PATTERNS already fences off node_modules and the +// generated caches, so recursion does not reintroduce vendored noise. +function recursivePatterns(patterns) { + return patterns.map((pattern) => `**/${pattern}`); +} + +function pathDepth(filePath) { + return filePath.split('/').length; +} + +// One glob walk per category (the glob library accepts a pattern array — far +// cheaper than one walk per pattern), with /-normalized output so reports and +// dedup keys are identical across platforms, and root-first ordering so +// "find the project manifest" reads keep resolving to the root file. +async function globUnique(patterns, rootDir) { + const matches = await glob(patterns, { + cwd: rootDir, + nodir: true, + dot: true, + ignore: IGNORE_PATTERNS, + }); + const unique = [...new Set(matches.map((match) => match.replace(/\\/g, '/')))]; + return unique.sort((a, b) => pathDepth(a) - pathDepth(b) || a.localeCompare(b)); +} + function readFileJson(filePath) { try { const raw = fs.readFileSync(filePath, 'utf8'); @@ -193,170 +159,131 @@ function detectTechStack(files) { return Array.from(techSet); } -function detectFrameworksFromPackageJson(rootDir, depFiles) { - const frameworks = []; - const pkgPath = depFiles.find((f) => path.basename(f) === 'package.json'); - - if (!pkgPath) return frameworks; - - const pkg = readProjectJson(rootDir, pkgPath); - if (!pkg) return frameworks; - - const allDeps = { - ...pkg.dependencies, - ...pkg.devDependencies, - ...pkg.peerDependencies, - }; - - if (allDeps['react']) frameworks.push('React'); - if (allDeps['vue']) frameworks.push('Vue'); - if (allDeps['@angular/core']) frameworks.push('Angular'); - if (allDeps['svelte']) frameworks.push('Svelte'); - if (allDeps['next']) frameworks.push('Next.js'); - if (allDeps['nuxt']) frameworks.push('Nuxt'); - if (allDeps['express']) frameworks.push('Express'); - if (allDeps['fastify']) frameworks.push('Fastify'); - if (allDeps['@nestjs/core']) frameworks.push('NestJS'); - if (allDeps['react-native']) frameworks.push('React Native'); - if (allDeps['expo']) frameworks.push('Expo'); - if (allDeps['electron']) frameworks.push('Electron'); - if (allDeps['@tauri-apps/api']) frameworks.push('Tauri'); +// In a monorepo every workspace manifest contributes frameworks, so the +// detectors below read ALL matching dep files, not just the first one found. +function eachDepFile(depFiles, matcher) { + return depFiles.filter((f) => matcher(path.basename(f), f)); +} - return frameworks; +function detectFrameworksFromPackageJson(rootDir, depFiles) { + const frameworks = new Set(); + for (const pkgPath of eachDepFile(depFiles, (base) => base === 'package.json')) { + const pkg = readProjectJson(rootDir, pkgPath); + if (!pkg) continue; + + const allDeps = { + ...pkg.dependencies, + ...pkg.devDependencies, + ...pkg.peerDependencies, + }; + + if (allDeps['react']) frameworks.add('React'); + if (allDeps['vue']) frameworks.add('Vue'); + if (allDeps['@angular/core']) frameworks.add('Angular'); + if (allDeps['svelte']) frameworks.add('Svelte'); + if (allDeps['next']) frameworks.add('Next.js'); + if (allDeps['nuxt']) frameworks.add('Nuxt'); + if (allDeps['express']) frameworks.add('Express'); + if (allDeps['fastify']) frameworks.add('Fastify'); + if (allDeps['@nestjs/core']) frameworks.add('NestJS'); + if (allDeps['react-native']) frameworks.add('React Native'); + if (allDeps['expo']) frameworks.add('Expo'); + if (allDeps['electron']) frameworks.add('Electron'); + if (allDeps['@tauri-apps/api']) frameworks.add('Tauri'); + } + return [...frameworks]; } function detectFrameworksFromRequirements(rootDir, depFiles) { - const frameworks = []; - const reqPath = depFiles.find((f) => path.basename(f) === 'requirements.txt'); - - if (!reqPath) return frameworks; - - const lines = readProjectLines(rootDir, reqPath); - const content = lines.join('\n').toLowerCase(); - - if (content.includes('django')) frameworks.push('Django'); - if (content.includes('flask')) frameworks.push('Flask'); - if (content.includes('fastapi')) frameworks.push('FastAPI'); - - return frameworks; + const frameworks = new Set(); + for (const reqPath of eachDepFile(depFiles, (base) => base === 'requirements.txt')) { + const content = readProjectLines(rootDir, reqPath).join('\n').toLowerCase(); + if (content.includes('django')) frameworks.add('Django'); + if (content.includes('flask')) frameworks.add('Flask'); + if (content.includes('fastapi')) frameworks.add('FastAPI'); + } + return [...frameworks]; } function detectFrameworksFromPyproject(rootDir, depFiles) { - const frameworks = []; - const pyprojectPath = depFiles.find((f) => path.basename(f) === 'pyproject.toml'); - - if (!pyprojectPath) return frameworks; - - const content = readProjectContent(rootDir, pyprojectPath).toLowerCase(); - - if (content.includes('django')) frameworks.push('Django'); - if (content.includes('flask')) frameworks.push('Flask'); - if (content.includes('fastapi')) frameworks.push('FastAPI'); - - return frameworks; + const frameworks = new Set(); + for (const pyprojectPath of eachDepFile(depFiles, (base) => base === 'pyproject.toml')) { + const content = readProjectContent(rootDir, pyprojectPath).toLowerCase(); + if (content.includes('django')) frameworks.add('Django'); + if (content.includes('flask')) frameworks.add('Flask'); + if (content.includes('fastapi')) frameworks.add('FastAPI'); + } + return [...frameworks]; } function detectFrameworksFromComposer(rootDir, depFiles) { - const frameworks = []; - const composerPath = depFiles.find((f) => path.basename(f) === 'composer.json'); - - if (!composerPath) return frameworks; - - const composer = readProjectJson(rootDir, composerPath); - if (!composer) return frameworks; - - const allDeps = { - ...composer.require, - ...composer['require-dev'], - }; - - if (allDeps && allDeps['laravel/framework']) frameworks.push('Laravel'); - - return frameworks; + const frameworks = new Set(); + for (const composerPath of eachDepFile(depFiles, (base) => base === 'composer.json')) { + const composer = readProjectJson(rootDir, composerPath); + if (!composer) continue; + const allDeps = { + ...composer.require, + ...composer['require-dev'], + }; + if (allDeps && allDeps['laravel/framework']) frameworks.add('Laravel'); + } + return [...frameworks]; } function detectFrameworksFromGemfile(rootDir, depFiles) { - const frameworks = []; - const gemfilePath = depFiles.find((f) => path.basename(f) === 'Gemfile'); - - if (!gemfilePath) return frameworks; - - const lines = readProjectLines(rootDir, gemfilePath); - const content = lines.join('\n').toLowerCase(); - - if (content.includes("'rails'") || content.includes('"rails"')) frameworks.push('Rails'); - - return frameworks; + const frameworks = new Set(); + for (const gemfilePath of eachDepFile(depFiles, (base) => base === 'Gemfile')) { + const content = readProjectLines(rootDir, gemfilePath).join('\n').toLowerCase(); + if (content.includes("'rails'") || content.includes('"rails"')) frameworks.add('Rails'); + } + return [...frameworks]; } function detectFrameworksFromPomXml(rootDir, depFiles) { - const frameworks = []; - const pomPath = depFiles.find((f) => path.basename(f) === 'pom.xml'); - - if (!pomPath) return frameworks; - - const content = readProjectContent(rootDir, pomPath).toLowerCase(); - - if (content.includes('spring-boot') || content.includes('springframework')) frameworks.push('Spring'); - - return frameworks; + const frameworks = new Set(); + for (const pomPath of eachDepFile(depFiles, (base) => base === 'pom.xml')) { + const content = readProjectContent(rootDir, pomPath).toLowerCase(); + if (content.includes('spring-boot') || content.includes('springframework')) frameworks.add('Spring'); + } + return [...frameworks]; } function detectFrameworksFromGradle(rootDir, depFiles) { - const frameworks = []; - const gradlePath = depFiles.find((f) => { - const base = path.basename(f); - return base === 'build.gradle' || base === 'build.gradle.kts'; - }); - - if (!gradlePath) return frameworks; - - const content = readProjectContent(rootDir, gradlePath).toLowerCase(); - - if (content.includes('spring-boot') || content.includes('org.springframework')) frameworks.push('Spring'); - - return frameworks; + const frameworks = new Set(); + for (const gradlePath of eachDepFile(depFiles, (base) => base === 'build.gradle' || base === 'build.gradle.kts')) { + const content = readProjectContent(rootDir, gradlePath).toLowerCase(); + if (content.includes('spring-boot') || content.includes('org.springframework')) frameworks.add('Spring'); + } + return [...frameworks]; } function detectFrameworksFromGoMod(rootDir, depFiles) { - const frameworks = []; - const goModPath = depFiles.find((f) => path.basename(f) === 'go.mod'); - - if (!goModPath) return frameworks; - - const content = readProjectContent(rootDir, goModPath); - - if (content.includes('gin-gonic/gin')) frameworks.push('Gin'); - if (content.includes('labstack/echo')) frameworks.push('Echo'); - if (content.includes('gofiber/fiber')) frameworks.push('Fiber'); - - return frameworks; + const frameworks = new Set(); + for (const goModPath of eachDepFile(depFiles, (base) => base === 'go.mod')) { + const content = readProjectContent(rootDir, goModPath); + if (content.includes('gin-gonic/gin')) frameworks.add('Gin'); + if (content.includes('labstack/echo')) frameworks.add('Echo'); + if (content.includes('gofiber/fiber')) frameworks.add('Fiber'); + } + return [...frameworks]; } function detectFrameworksFromCsproj(rootDir, depFiles) { - const frameworks = []; - const csprojPath = depFiles.find((f) => path.extname(f) === '.csproj'); - - if (!csprojPath) return frameworks; - - const content = readProjectContent(rootDir, csprojPath); - - if (content.includes('Microsoft.AspNetCore')) frameworks.push('ASP.NET'); - - return frameworks; + const frameworks = new Set(); + for (const csprojPath of eachDepFile(depFiles, (base, full) => path.extname(full) === '.csproj')) { + const content = readProjectContent(rootDir, csprojPath); + if (content.includes('Microsoft.AspNetCore')) frameworks.add('ASP.NET'); + } + return [...frameworks]; } function detectFrameworksFromPubspec(rootDir, depFiles) { - const frameworks = []; - const pubspecPath = depFiles.find((f) => path.basename(f) === 'pubspec.yaml'); - - if (!pubspecPath) return frameworks; - - const content = readProjectContent(rootDir, pubspecPath).toLowerCase(); - - if (content.includes('flutter')) frameworks.push('Flutter'); - - return frameworks; + const frameworks = new Set(); + for (const pubspecPath of eachDepFile(depFiles, (base) => base === 'pubspec.yaml')) { + const content = readProjectContent(rootDir, pubspecPath).toLowerCase(); + if (content.includes('flutter')) frameworks.add('Flutter'); + } + return [...frameworks]; } function detectFrameworksFromConfigFiles(rootDir, configFiles, files) { @@ -513,152 +440,90 @@ export function readFileSafe(filePath) { } } -export async function scanProject(rootDir) { - console.log('Scanning project structure...'); - - const sourceGlob = buildSourceGlobPattern(); - - const sourceFiles = await glob(sourceGlob, { - cwd: rootDir, - nodir: true, - dot: true, - ignore: IGNORE_PATTERNS, - }); - - const configPatterns = [ - '.env', - '.env.local', - '.env.development', - '.env.production', - '.env.staging', - '.env.test', - 'docker-compose.yml', - 'docker-compose.yaml', - 'Dockerfile', - '.dockerignore', - 'nginx.conf', - 'apache2.conf', - '.htaccess', - '.github/workflows/*.yml', - '.github/workflows/*.yaml', - '.gitlab-ci.yml', - 'Jenkinsfile', - '.circleci/config.yml', - 'bitbucket-pipelines.yml', - '*.tf', - '*.tfvars', - '.eslintrc', - '.eslintrc.*', - 'security.txt', - 'package.json', - 'tsconfig.json', - 'webpack.config.*', - 'vite.config.*', - 'next.config.*', - 'nuxt.config.*', - 'angular.json', - 'vue.config.*', - 'svelte.config.*', - 'gatsby-config.*', - '*.pem', - '*.crt', - '*.key', - 'terraform/*.tf', - 'terraform/*.tfvars', - ]; - - const configFiles = []; - for (const pattern of configPatterns) { - try { - const matches = await glob(pattern, { - cwd: rootDir, - nodir: true, - dot: true, - ignore: IGNORE_PATTERNS, - }); - for (const match of matches) { - if (!configFiles.includes(match)) { - configFiles.push(match); - } - } - } catch { - // skip invalid patterns - } - } +const CONFIG_FILE_PATTERNS = [ + '.env', + '.env.local', + '.env.development', + '.env.production', + '.env.staging', + '.env.test', + 'docker-compose.yml', + 'docker-compose.yaml', + 'Dockerfile', + '.dockerignore', + 'nginx.conf', + 'apache2.conf', + '.htaccess', + '.github/workflows/*.yml', + '.github/workflows/*.yaml', + '.gitlab-ci.yml', + 'Jenkinsfile', + '.circleci/config.yml', + 'bitbucket-pipelines.yml', + '*.tf', + '*.tfvars', + '.eslintrc', + '.eslintrc.*', + 'security.txt', + 'package.json', + 'tsconfig.json', + 'webpack.config.*', + 'vite.config.*', + 'next.config.*', + 'nuxt.config.*', + 'angular.json', + 'vue.config.*', + 'svelte.config.*', + 'gatsby-config.*', + '*.pem', + '*.crt', + '*.key', +]; - const depPatterns = [ - 'package.json', - 'package-lock.json', - 'yarn.lock', - 'pnpm-lock.yaml', - 'requirements.txt', - 'pyproject.toml', - 'setup.py', - 'setup.cfg', - 'Pipfile', - 'Pipfile.lock', - 'poetry.lock', - 'go.mod', - 'go.sum', - 'Cargo.toml', - 'Cargo.lock', - 'pom.xml', - 'build.gradle', - 'build.gradle.kts', - 'Gemfile', - 'Gemfile.lock', - '*.gemspec', - 'composer.json', - 'composer.lock', - '*.csproj', - '*.sln', - 'packages.config', - 'nuget.config', - 'pubspec.yaml', - 'pubspec.lock', - 'Package.swift', - '*.lpi', - '*.dproj', - ]; +const DEP_FILE_PATTERNS = [ + 'package.json', + 'package-lock.json', + 'yarn.lock', + 'pnpm-lock.yaml', + 'requirements.txt', + 'pyproject.toml', + 'setup.py', + 'setup.cfg', + 'Pipfile', + 'Pipfile.lock', + 'poetry.lock', + 'go.mod', + 'go.sum', + 'Cargo.toml', + 'Cargo.lock', + 'pom.xml', + 'build.gradle', + 'build.gradle.kts', + 'Gemfile', + 'Gemfile.lock', + '*.gemspec', + 'composer.json', + 'composer.lock', + '*.csproj', + '*.sln', + 'packages.config', + 'nuget.config', + 'pubspec.yaml', + 'pubspec.lock', + 'Package.swift', + '*.lpi', + '*.dproj', +]; - const depFiles = []; - for (const pattern of depPatterns) { - try { - const matches = await glob(pattern, { - cwd: rootDir, - nodir: true, - dot: true, - ignore: IGNORE_PATTERNS, - }); - for (const match of matches) { - if (!depFiles.includes(match)) { - depFiles.push(match); - } - } - } catch { - // skip invalid patterns - } - } +export async function scanProject(rootDir) { + console.log('Scanning project structure...'); - const baasPatterns = getBaasFilePatterns(); - const baasFiles = []; - for (const pattern of baasPatterns) { - try { - const matches = await glob(pattern, { - cwd: rootDir, - nodir: true, - dot: true, - ignore: IGNORE_PATTERNS, - }); - for (const match of matches) { - if (!baasFiles.includes(match)) { - baasFiles.push(match); - } - } - } catch { - // skip invalid patterns - } - } + const [sourceFiles, configFiles, depFiles, baasFiles] = await Promise.all([ + globUnique([buildSourceGlobPattern()], rootDir), + globUnique(recursivePatterns(CONFIG_FILE_PATTERNS), rootDir), + globUnique(recursivePatterns(DEP_FILE_PATTERNS), rootDir), + globUnique(recursivePatterns(getBaasFilePatterns()), rootDir), + ]); const techStack = detectTechStack(sourceFiles); diff --git a/csreview/test/agent-name.test.js b/csreview/test/agent-name.test.js new file mode 100644 index 0000000..8cc4e85 --- /dev/null +++ b/csreview/test/agent-name.test.js @@ -0,0 +1,23 @@ +// @ts-check +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { sanitizeAgentName } from '../src/agentName.js'; + +// Report filenames embed the agent name (_security-report.html, +// _local-dast-report.html, _db-dump-guide.html). The sanitizer +// used to exist as THREE separate copies (index.js, localDast.js, +// dumpGuide.js); if they drifted, the static-scan and DAST reports for the +// same agent could land under different prefixes. One module, one behavior. + +test('sanitizeAgentName normalizes names to safe lowercase file prefixes', () => { + assert.equal(sanitizeAgentName('Claude Code'), 'claude-code'); + assert.equal(sanitizeAgentName(' GPT_5 '), 'gpt_5'); + assert.equal(sanitizeAgentName('a--b!!c'), 'a-b-c'); + assert.equal(sanitizeAgentName('-edge-'), 'edge'); +}); + +test('sanitizeAgentName falls back to codex for empty or fully-stripped input', () => { + assert.equal(sanitizeAgentName(''), 'codex'); + assert.equal(sanitizeAgentName(undefined), 'codex'); + assert.equal(sanitizeAgentName('***'), 'codex'); +}); diff --git a/csreview/test/cli-args.test.js b/csreview/test/cli-args.test.js new file mode 100644 index 0000000..7c60361 --- /dev/null +++ b/csreview/test/cli-args.test.js @@ -0,0 +1,61 @@ +// @ts-check +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { parseCliArgs, normalizeFailOn, countFindingsAtOrAbove } from '../src/cliArgs.js'; + +// The CLI is a security gate: a mistyped flag must be a hard error, never a +// silently ignored no-op (`--basline x.json` running WITHOUT the baseline is +// exactly the failure mode a scanner cannot afford). + +test('parseCliArgs rejects unknown flags instead of silently ignoring them', () => { + assert.throws(() => parseCliArgs(['.', '--basline', 'known.json']), /basline/); + assert.throws(() => parseCliArgs(['.', '--fail-no', 'high']), /fail-no/); +}); + +test('parseCliArgs parses the documented surface', () => { + const parsed = parseCliArgs([ + 'C:/proj', + '--output', + 'reports', + '--agent-name', + 'claude', + '--baseline', + 'base.json', + '--strict-partials', + '--fail-on', + 'high', + ]); + assert.equal(parsed.targetArg, 'C:/proj'); + assert.equal(parsed.output, 'reports'); + assert.equal(parsed.agentName, 'claude'); + assert.equal(parsed.baseline, 'base.json'); + assert.equal(parsed.strictPartials, true); + assert.equal(parsed.failOn, 'HIGH'); + assert.equal(parsed.version, false); +}); + +test('parseCliArgs supports -o, -h, -v shorthands and --doctor with target', () => { + assert.equal(parseCliArgs(['.', '-o', 'out']).output, 'out'); + assert.equal(parseCliArgs(['-h']).help, true); + assert.equal(parseCliArgs(['-v']).version, true); + const doctor = parseCliArgs(['--doctor', 'C:/proj']); + assert.equal(doctor.doctor, true); + assert.equal(doctor.targetArg, 'C:/proj'); +}); + +test('normalizeFailOn validates the severity level', () => { + assert.equal(normalizeFailOn('high'), 'HIGH'); + assert.equal(normalizeFailOn('CRITICAL'), 'CRITICAL'); + assert.equal(normalizeFailOn(undefined), null); + assert.throws(() => normalizeFailOn('severe'), /fail-on/); + assert.throws(() => normalizeFailOn('info'), /fail-on/); +}); + +test('countFindingsAtOrAbove counts findings at or above the gate severity', () => { + const counts = { CRITICAL: 1, HIGH: 2, MEDIUM: 3, LOW: 4, INFO: 5 }; + assert.equal(countFindingsAtOrAbove(counts, 'CRITICAL'), 1); + assert.equal(countFindingsAtOrAbove(counts, 'HIGH'), 3); + assert.equal(countFindingsAtOrAbove(counts, 'MEDIUM'), 6); + assert.equal(countFindingsAtOrAbove({ HIGH: 0 }, 'HIGH'), 0); + assert.equal(countFindingsAtOrAbove({}, 'LOW'), 0); +}); diff --git a/csreview/test/detector-precision.test.js b/csreview/test/detector-precision.test.js index 9d070a9..d6e380a 100644 --- a/csreview/test/detector-precision.test.js +++ b/csreview/test/detector-precision.test.js @@ -95,6 +95,27 @@ const POSITIVES = [ cwe: 'CWE-22', code: 'import fs from "fs";\nexport const read = (req, cb) => fs.readFile(req.query.path, cb);\n', }, + { + name: 'js-xxe-noent', + file: 'src/m.js', + language: 'javascript', + cwe: 'CWE-611', + code: 'import libxmljs from "libxmljs";\nexport const parse = (xml) => libxmljs.parseXml(xml, { noent: true });\n', + }, + { + name: 'py-xxe-resolve-entities', + file: 'src/m2.py', + language: 'python', + cwe: 'CWE-611', + code: 'from lxml import etree\n\nparser = etree.XMLParser(resolve_entities=True)\n', + }, + { + name: 'php-xxe-libxml-noent', + file: 'src/m3.php', + language: 'php', + cwe: 'CWE-611', + code: ' x.excludes;\n', }, + // XML_XXE must require an explicitly insecure entity configuration. Browser + // DOMParser never resolves external entities, and noent:false / nonet:true / + // resolve_entities=False are the SAFE configurations. + { + name: 'domparser-benign', + file: 'src/n14.js', + language: 'javascript', + code: 'export const parse = (html) => new DOMParser().parseFromString(html, "text/html");\n', + }, + { + name: 'libxml-safe-config', + file: 'src/n15.js', + language: 'javascript', + code: 'import libxml from "libxmljs";\nexport const parse = (data) => libxml.parseXml(data, { noent: false, nonet: true });\n', + }, + { + name: 'py-xxe-safe', + file: 'src/n16.py', + language: 'python', + code: 'from lxml import etree\n\nparser = etree.XMLParser(resolve_entities=False)\n', + }, ]; function runOne(sample) { @@ -216,3 +258,30 @@ test('detector produces no HIGH/CRITICAL false positives on the negative corpus' } assert.equal(falsePositives.length, 0, `unexpected false positives: ${falsePositives.join(' | ')}`); }); + +// Regression guard for the XML_XXE pattern: the old `.*?(?!.*noent)` lookahead +// was always satisfiable, so ANY line mentioning an XML parser (including the +// entity-free browser DOMParser) produced a CRITICAL. The pattern must fire on +// explicitly insecure entity configuration and stay silent otherwise. +test('XML_XXE fires only on explicitly insecure entity configuration', () => { + const insecure = POSITIVES.filter((sample) => sample.cwe === 'CWE-611'); + assert.ok(insecure.length >= 3, 'expected XXE positives in the corpus'); + for (const sample of insecure) { + const findings = runOne(sample); + assert.ok( + findings.some((f) => canonicalCwe(f.cwe) === 'CWE-611'), + `${sample.name}: expected a CWE-611 finding`, + ); + } + for (const sample of NEGATIVES.filter((s) => + ['domparser-benign', 'libxml-safe-config', 'py-xxe-safe'].includes(s.name), + )) { + const findings = runOne(sample); + const xxe = findings.filter((f) => canonicalCwe(f.cwe) === 'CWE-611'); + assert.equal( + xxe.length, + 0, + `${sample.name}: safe XML usage must not raise CWE-611 (got ${xxe.map((f) => f.id).join(', ')})`, + ); + } +}); diff --git a/csreview/test/languages.test.js b/csreview/test/languages.test.js new file mode 100644 index 0000000..4916eb6 --- /dev/null +++ b/csreview/test/languages.test.js @@ -0,0 +1,43 @@ +// @ts-check +import test from 'node:test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { getLanguage, LANG_MAP, EXTENSION_TO_TECH } from '../src/languages.js'; +import { detectVulnerabilities } from '../src/detector.js'; + +// Extension→language used to live in THREE divergent maps (index.js LANG_MAP, +// detector.js LANGUAGE_MAP, scanner.js EXTENSION_TO_TECH). The detector copy +// was already stale: .pyw never resolved to python, so Python-specific rules +// (pickle/yaml/SQL) silently skipped *.pyw files. + +test('getLanguage resolves common and previously-missing extensions', () => { + assert.equal(getLanguage('src/app.ts'), 'typescript'); + assert.equal(getLanguage('src/tool.pyw'), 'python'); + assert.equal(getLanguage('src/main.pas'), 'delphi'); + assert.equal(getLanguage('README'), 'unknown'); + assert.equal(getLanguage('archive.unknownext'), 'unknown'); +}); + +test('language and tech maps agree on the extensions they share', () => { + for (const ext of ['py', 'pyw', 'go', 'rs', 'kt', 'dart']) { + assert.ok(LANG_MAP[ext], `LANG_MAP missing ${ext}`); + assert.ok(EXTENSION_TO_TECH[ext], `EXTENSION_TO_TECH missing ${ext}`); + } +}); + +test('detector applies Python-specific rules to .pyw files via the shared fallback', () => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), 'csreview-lang-')); + const rel = 'src/loader.pyw'; + const abs = path.join(root, ...rel.split('/')); + fs.mkdirSync(path.dirname(abs), { recursive: true }); + fs.writeFileSync(abs, 'import pickle\n\ndef load(data):\n return pickle.loads(data)\n', 'utf8'); + + // No language provided: the detector must fall back to the shared map. + const findings = detectVulnerabilities({ root, files: [{ path: rel, kind: 'source' }] }); + assert.ok( + findings.some((f) => String(f.cwe).includes('CWE-502')), + `expected CWE-502 from PY_DESERIALIZE on a .pyw file, got: ${findings.map((f) => f.id).join(', ') || 'none'}`, + ); +}); diff --git a/csreview/test/scanner.test.js b/csreview/test/scanner.test.js new file mode 100644 index 0000000..a701d9f --- /dev/null +++ b/csreview/test/scanner.test.js @@ -0,0 +1,65 @@ +// @ts-check +import test from 'node:test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { scanProject } from '../src/scanner.js'; + +// Monorepo coverage: config, dependency, and BaaS files live in nested +// workspaces (apps/*, services/*, packages/*), not only at the project root. +// The scanner must discover them recursively while still honoring the +// generated-cache exclusions (node_modules etc.). + +function makeMonorepo() { + const root = fs.mkdtempSync(path.join(os.tmpdir(), 'csreview-scanner-')); + const write = (rel, content) => { + const abs = path.join(root, ...rel.split('/')); + fs.mkdirSync(path.dirname(abs), { recursive: true }); + fs.writeFileSync(abs, content, 'utf8'); + }; + write('package.json', JSON.stringify({ name: 'monorepo', private: true })); + write('apps/web/package.json', JSON.stringify({ name: 'web', dependencies: { nuxt: '^4.0.0' } })); + write('apps/web/.env.production', 'PLACEHOLDER=value\n'); + write('services/api/Dockerfile', 'FROM node:24-alpine\n'); + write('services/api/firestore.rules', "rules_version = '2';\n"); + write('packages/lib/src/index.js', 'export const x = 1;\n'); + write('node_modules/leftpad/package.json', JSON.stringify({ name: 'leftpad' })); + write('node_modules/leftpad/.env', 'SECRET=should-not-be-scanned\n'); + return root; +} + +test('scanProject discovers nested config/dep/BaaS files in a monorepo', async () => { + const root = makeMonorepo(); + const info = await scanProject(root); + + assert.ok(info.depFiles.includes('apps/web/package.json'), `nested package.json missing: ${info.depFiles}`); + assert.ok(info.configFiles.includes('apps/web/.env.production'), `nested .env missing: ${info.configFiles}`); + assert.ok(info.configFiles.includes('services/api/Dockerfile'), `nested Dockerfile missing: ${info.configFiles}`); + assert.ok( + info.baasFiles.includes('services/api/firestore.rules'), + `nested firestore.rules missing: ${info.baasFiles}`, + ); +}); + +test('scanProject detects frameworks declared in nested workspace manifests', async () => { + const root = makeMonorepo(); + const info = await scanProject(root); + assert.ok(info.frameworks.includes('Nuxt'), `Nuxt not detected from apps/web/package.json: ${info.frameworks}`); +}); + +test('scanProject keeps generated caches excluded and orders dep files root-first', async () => { + const root = makeMonorepo(); + const info = await scanProject(root); + + const all = [...info.files, ...info.configFiles, ...info.depFiles, ...info.baasFiles]; + assert.ok( + !all.some((f) => f.includes('node_modules')), + `node_modules leaked into discovery: ${all.filter((f) => f.includes('node_modules'))}`, + ); + assert.ok( + all.every((f) => !f.includes('\\')), + 'discovered paths must be /-normalized for cross-platform reports', + ); + assert.equal(info.depFiles[0], 'package.json', 'root manifest must sort before nested ones'); +}); diff --git a/csreview/test/tool-env.test.js b/csreview/test/tool-env.test.js index 4d6a0a6..ff27806 100644 --- a/csreview/test/tool-env.test.js +++ b/csreview/test/tool-env.test.js @@ -46,3 +46,39 @@ test('semgrepExcludeArgs excludes build outputs and vendored dirs (the DeckMidia assert.ok(excluded.has(dir), `semgrep must exclude ${dir}`); } }); + +// --tool-timeout / --semgrep-config wiring: the scan must be able to run +// against local rules (air-gapped, no registry metrics) and a timed-out tool +// must say so explicitly — "unavailable" hid that the scan silently degraded. + +test('buildSemgrepArgs defaults to --config auto without disabling metrics', async () => { + const { buildSemgrepArgs } = await import('../src/index.js'); + const args = buildSemgrepArgs('/proj'); + const i = args.indexOf('--config'); + assert.equal(args[i + 1], 'auto'); + assert.ok(!args.includes('--metrics=off'), 'auto config requires registry metrics; must not disable them'); + assert.equal(args[args.length - 1], '/proj'); + assert.ok(args.includes('--exclude'), 'build-output excludes must be preserved'); +}); + +test('buildSemgrepArgs uses a custom config with metrics off (offline-friendly)', async () => { + const { buildSemgrepArgs } = await import('../src/index.js'); + const args = buildSemgrepArgs('/proj', { config: './semgrep-rules' }); + const i = args.indexOf('--config'); + assert.equal(args[i + 1], './semgrep-rules'); + assert.ok(args.includes('--metrics=off')); +}); + +test('toolErrorMessage explains a timeout and how to raise it', async () => { + const { toolErrorMessage } = await import('../src/index.js'); + const err = Object.assign(new Error('Command failed: semgrep'), { killed: true, signal: 'SIGTERM' }); + const msg = toolErrorMessage('semgrep', err, 120000); + assert.match(msg, /timed out after 120s/i); + assert.match(msg, /--tool-timeout/); +}); + +test('toolErrorMessage keeps the not-found message for ENOENT', async () => { + const { toolErrorMessage } = await import('../src/index.js'); + const err = Object.assign(new Error('spawn semgrep ENOENT'), { code: 'ENOENT' }); + assert.match(toolErrorMessage('semgrep', err), /not found in PATH/); +}); From abe320e824718b796c542f310b069726b37831f6 Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 10 Jun 2026 15:04:51 -0300 Subject: [PATCH 2/6] chore: ignore stray report copies outside csreview-reports/ *_security.sarif, *_local-dast-report*.html, *_local-dast-findings*.md, and *_db-dump-guide.html now match the existing stray-copy patterns. Co-Authored-By: Claude Fable 5 --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index cb04927..d6301b5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,14 @@ security-findings.md *_security-findings.md **/*_security-report.html **/*_security-findings.md +*_security.sarif +**/*_security.sarif +*_local-dast-report*.html +*_local-dast-findings*.md +**/*_local-dast-report*.html +**/*_local-dast-findings*.md +*_db-dump-guide.html +**/*_db-dump-guide.html CSREVIEW-ANALISES.md CSREVIEW-ANALISES*.md From 21a27b9a218a6da1d5aaf3b99884d7ff9a9f22cb Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 10 Jun 2026 15:03:42 -0300 Subject: [PATCH 3/6] docs: lean SKILL.md core + on-demand reference/, honest README landing SKILL.md drops from 1948 to ~250 lines: engine-first execution workflow (run the CLI; never handcraft reports), consolidated core rules, and an explicit no-fabricated-metrics rule (the engine computes no ASVS percentages, SLSA levels, or per-article compliance verdicts). DAST-CONFIRMED is documented as a reserved label the built-in probe never emits, and dotnet build is no longer listed as a scanner. Checklists, compliance tables, tooling commands, the subagent protocol, and report anatomy move to csreview/reference/*.md (shipped in the npm package, loaded on demand). README is rebuilt as an honest landing page (orchestration + corroboration + evidence layer, with an explicit limits section) and keeps the verbatim SKILL.md mirror. The doc-honesty contracts in analysis.test.js now assert across README + SKILL.md + reference/*. Co-Authored-By: Claude Fable 5 --- README.md | 2682 ++----------------- csreview/SKILL.md | 2019 ++------------ csreview/package.json | 1 + csreview/reference/compliance-frameworks.md | 103 + csreview/reference/local-dast.md | 58 + csreview/reference/reports.md | 74 + csreview/reference/review-modes.md | 52 + csreview/reference/security-checklists.md | 199 ++ csreview/reference/subagents.md | 66 + csreview/reference/tooling.md | 89 + csreview/test/analysis.test.js | 30 +- 11 files changed, 1058 insertions(+), 4315 deletions(-) create mode 100644 csreview/reference/compliance-frameworks.md create mode 100644 csreview/reference/local-dast.md create mode 100644 csreview/reference/reports.md create mode 100644 csreview/reference/review-modes.md create mode 100644 csreview/reference/security-checklists.md create mode 100644 csreview/reference/subagents.md create mode 100644 csreview/reference/tooling.md diff --git a/README.md b/README.md index 746b04f..2222a03 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,23 @@ [![Skill Type](https://img.shields.io/badge/Type-AI%20Agent%20Skill-blue)]() [![Compatibility](https://img.shields.io/badge/Compatibility-Trae%20%7C%20Claude%20Code%20%7C%20Codex%20%7C%20Qwen%20%7C%20OpenCode%20%7C%20Antigravity%20%7C%20Qoder-green)]() -## Security tooling CSReview relies on (and can install for you) +**CSReview is an orchestration, corroboration, and evidence layer for security review of the local workspace — built for AI coding agents and the humans who supervise them.** It is local, development-time security alignment (SAST/SCA + actionable reports + agent methodology): **not** an automated penetration test, **not** a replacement for Semgrep or any scanner it orchestrates, and **read-only on your source code**. + +## What it actually does + +One command runs the whole pipeline deterministically: -CSReview is **local, development-time security alignment** (SAST/SCA + actionable reports + agent support) — **not** an automated penetration test, and it is **read-only on your source code**. Its fidelity — results faithful to the objective, with **far fewer false positives** — comes from running real, best-in-class security tools and corroborating them with its own heuristics (a finding confirmed by both a tool and the detector is marked `CONFIRMED`). +1. **Discovers** the workspace (source, configs, `.env`, lockfiles, IaC, BaaS rules — recursively, monorepo-aware) and detects the stack. +2. **Orchestrates real security tools** — Semgrep (required baseline), the lockfile-selected package audit (npm/pnpm/bun), OSV-Scanner, and (opt-in) Gitleaks, Trivy, gosec, Bandit — and parses their JSON output. +3. **Adds its own heuristic detector** for secrets (redacted in evidence), config/IaC/BaaS misconfigurations, and common vulnerability shapes — a complementary net, not a taint-tracking SAST. +4. **Corroborates**: findings are deduplicated across sources by `file:line:CWE`; evidence seen by more than one independent source is promoted to `CONFIRMED`, and every finding carries an honest confidence label (`CONFIRMED` / `TOOL-ONLY` / heuristic `HIGH|MEDIUM|LOW`). +5. **Reports for both audiences**: an HTML report for humans, a Markdown report for coding agents to plan remediation from, and SARIF 2.1.0 for CI — plus `--fail-on ` so a pipeline can block merges, and `--baseline` so CI fails only on NEW findings. + +What it does **not** do — said up front: it does not modify your code, it does not probe deployed systems, it does not compute compliance verdicts (compliance fields are CWE correlation — indicative, never an audited compliance verification), and a clean report is evidence of absence-of-detection, not proof of security. + +## Security tooling CSReview relies on (and can install for you) -For the highest-quality result, CSReview uses these official tools: +CSReview's fidelity — results faithful to the objective, with **far fewer false positives** — comes from running real, best-in-class security tools and corroborating them with its own heuristics (a finding confirmed by both a tool and the detector is marked `CONFIRMED`). | Tool | Purpose | Official source | |------|---------|-----------------| @@ -30,9 +42,35 @@ For the highest-quality result, CSReview uses these official tools: Prefer to manage them yourself? Install the tools and CSReview will use whatever is already on your `PATH`; or run without them. Either way, the report tells you which tools ran and which were skipped. +## Quickstart + +```bash +# 1. Get the engine (distributed via GitHub) +git clone https://github.com/decksoftware/csreview.git +cd csreview/csreview && npm install -g . + +# 2. Check your scanner toolchain +csreview --doctor . + +# 3. Scan a project (read-only; reports land in /csreview-reports/) +csreview /path/to/project --agent-name claude + +# 4. Gate your CI +csreview . --agent-name ci --fail-on high # exit 1 if HIGH/CRITICAL remain +``` + +Key CLI options: `--fail-on ` (CI gate) · `--baseline ` / `--update-baseline` (fail only on NEW findings) · `--provision-tools` (opt-in tool install, SHA-256 verified) · `--tool-timeout ` · `--semgrep-config ` (local rules, offline-friendly) · `--local-dast-url --confirm-local-dast` (optional post-remediation local probe) · `--doctor` · `--version`. Unknown flags are hard errors — a mistyped option aborts instead of silently changing what is audited. A `.csreview-ignore` file (gitignore-style) suppresses report findings for matching paths without touching your project. + +## Honest limits + +- The built-in regex detector is line-oriented: it catches secrets, misconfigurations, and common shapes, but it has no taint tracking or cross-file analysis — that is what Semgrep (and optionally CodeQL) are for, which is why Semgrep is the **required baseline** and runs marked lower-confidence without it. +- Language-specific engine rules exist for JavaScript/TypeScript, Python, C#, Go, C/C++, and Delphi; other stacks lean on Semgrep + OSV-Scanner + agent checklists. +- Compliance output (LGPD/GDPR/SOC 2/HIPAA/CCPA-CPRA, OWASP ASVS, SLSA) is **indicative correlation by CWE** to support a human review — the engine computes no coverage percentages and no per-article verdicts, and the agent instructions forbid fabricating them. +- The optional Phase 9 "local DAST" is a conservative loopback-only HTTP probe (headers, CORS, reachability) with hard engine guards — it is not a penetration test. + ## Canonical Agent Instructions -The most important artifact in this repository is [csreview/SKILL.md](csreview/SKILL.md): this is the exact instruction file loaded by coding agents. It is mirrored below so GitHub visitors can evaluate the real CSReview behavior from the repository landing page without cloning. +The most important artifact in this repository is [csreview/SKILL.md](csreview/SKILL.md): the exact instruction file loaded by coding agents, kept deliberately lean. Detailed checklists and protocols live in [csreview/reference/](csreview/reference/) and are loaded on demand. SKILL.md is mirrored below so GitHub visitors can evaluate the real CSReview behavior from the landing page without cloning.
Expand the full SKILL.md read by coding agents @@ -46,9 +84,16 @@ description: "Development-time local workspace security alignment for codebases. # CSReview - Code Security Review -## Overview +## What CSReview Is + +CSReview performs development-time security alignment for the local workspace a developer is actively building. It applies a penetration tester's adversarial mindset to the project's local source, configuration, dependencies, and infrastructure files (static SAST + SCA). It does NOT perform live penetration testing against running, deployed, or production systems. -This skill performs development-time security alignment for the local workspace a developer is actively building. It applies a penetration tester's adversarial mindset to the project's local source, configuration, dependencies, and infrastructure files (static SAST + SCA). It does NOT perform live penetration testing against running, deployed, or production systems. It identifies vulnerabilities, data leakage risks, misconfigurations, and security flaws, then generates: +It is two things working together, and the agent must keep them straight: + +1. **A deterministic engine** (the `csreview` CLI). It discovers the workspace, runs and parses the external security tools, applies its own heuristic detector, deduplicates evidence across sources (promoting corroborated findings to `CONFIRMED`), scores the result, and writes ALL report files. The engine is the single writer of reports. +2. **An agent methodology** (this document + `reference/`). The agent runs the engine, then adds what tools cannot: contextual review of flagged code, framework research, remediation planning, and honest communication of confidence and limits. + +CSReview's value is orchestration, corroboration, and evidence — it complements Semgrep and the other scanners; it does not replace them. Its built-in regex detector is a complementary net (secrets, misconfigurations, BaaS rules, common injection shapes), not a taint-tracking SAST. ## Scope @@ -59,2547 +104,290 @@ This skill performs development-time security alignment for the local workspace ## Ethical Use & Attribution -CSReview is a white-hat security alignment tool. You may copy, fork, adapt, and replicate it under the MIT License, but the project asks that it be used for good: authorized security reviews, local development hardening, education, and remediation work in the spirit of an ethical hacker / White Hat Hacker. Do not use CSReview to support unauthorized intrusion, exploitation, credential theft, data exfiltration, surveillance, or harm. - -Credit should be preserved where practical: CSReview is a Deck Software project idealized by Márcio PS, built with assistance, review, and ideas from AI coding agents and tools including Claude Code, Trae, MiniMax, Qwen, Cascade da Windsurf, Codex, GLM 5.1, MiMo V2.5 Pro, and other reviewer agents. - -1. **HTML Report** (`csreview-reports/_security-report.html`) - Visual report for human review with executive summary, charts, and detailed findings -2. **Markdown Report** (`csreview-reports/_security-findings.md`) - Structured report for humans and coding agents to understand, prioritize, and plan remediations without CSReview modifying the audited code -3. **SARIF Report** (`csreview-reports/_security.sarif`) - SARIF 2.1.0 for CI pipelines and GitHub code scanning ingestion. It never embeds raw vulnerable code, so secrets are not leaked into the uploaded artifact. - -**CSReview is READ-ONLY**: It never modifies, deletes, moves, or creates source code in the analyzed project. It only identifies problems, locates them precisely, and suggests remediation approaches based on the frameworks and technologies in use. The actual fixes are applied later by the human developer or a coding agent after understanding the project context, schema, tests, and regression risk. When encountering unfamiliar frameworks, CSReview researches official documentation and community forums to provide accurate recommendations. - -**Global Skill Installation Policy**: CSReview is a global agent skill. It MUST be installed and loaded from the agent's global skills/instructions environment, such as `~/.codex/skills/csreview`, `~/.agents/skills/csreview`, `~/.trae/skills/csreview`, or `~/.claude/skills/csreview`. The agent MUST NOT copy, scaffold, install, update, delete, or move the CSReview skill inside the project being audited, including `/.trae/skills/csreview`, `/.codex/skills/csreview`, `/.agents/skills/csreview`, `/.claude/skills/csreview`, `/AGENTS.md`, `/CLAUDE.md`, `.cursorrules`, or `.windsurfrules`, unless the user explicitly asks for project-local installation. Generated reports may be written to the selected output directory, but those reports are audit artifacts, not a skill installation. Likewise, opt-in tool provisioning (`--provision-tools`) writes only verified tool binaries into an isolated, gitignored `.csreview/` workspace inside the project — that is a local tool cache, not a skill installation and not a modification of the audited source. - -**Semgrep is mandatory as a baseline SAST attempt**: every CSReview run MUST attempt to execute `semgrep --version` and `semgrep --config auto --json --quiet ` before relying on agent-only analysis. Semgrep is a required external CLI tool, not a normal bundled npm dependency; install it with `pipx install semgrep`, `uv tool install semgrep`, Homebrew, Docker, or the platform package manager. If Semgrep is unavailable, the report MUST state that the run has lower confidence and include installation instructions. - -**Dependency SCA complements Semgrep**: when available, the deterministic npm engine orchestrates and parses Node package audit tools selected by lockfile: `npm audit --json` for npm lockfiles, `pnpm audit --json` for `pnpm-lock.yaml`, and `bun audit --json` for `bun.lockb`/`bun.lock` (npm/pnpm take priority when more than one lockfile is present). It also parses `osv-scanner scan --format json ` for multi-ecosystem lockfile/manifests. These tools complement Semgrep by identifying known vulnerable dependency versions without changing source code or package files. Framework-native lint/scanning tools such as ESLint security plugins, pip-audit, Bandit, Gosec, cargo audit, dotnet vulnerable package checks, Checkov, Hadolint, Trivy, Snyk, and CodeQL are agent-recommended stack-native tools: the agent may run them when relevant and available, but they are not parsed by the npm engine unless explicitly added to the engine-orchestrated tool list. - -**Config and BaaS misconfiguration detection**: on files classified as configuration/IaC/BaaS (Firebase/Firestore/Storage rules, SQL migrations, Dockerfiles, Kubernetes/Compose YAML, Terraform, ORM config), CSReview additionally checks for high-signal misconfigurations such as public BaaS rules (`allow ... if true`), disabled Row Level Security, disabled TLS verification, `0.0.0.0/0` network ingress, public object-storage ACLs, privileged/run-as-root containers, world-writable permissions, and unpinned `:latest` base images. These config patterns are scoped to those file kinds and are not run against application source code, to keep false positives low. - -**CI integration and noise control**: CSReview also emits a SARIF 2.1.0 report (`_security.sarif`) for CI pipelines and code-scanning dashboards. A `.csreview-ignore` file at the project root (gitignore-style globs: `**`, `*`, `?`, anchored `/x`, directory `x/`, and `!negation`) suppresses findings for matching paths in the report only — it is read-only and never modifies the project. A baseline of known findings can be recorded with `--update-baseline` and enforced with `--baseline ` so CI fails only on NEW findings; baseline fingerprints are line-independent so they survive code shifting. - -**Pre-flight checks (read-only, fail-open)**: before a scan CSReview can check whether a newer CSReview version exists in the official repository — this is advisory only, it never auto-updates itself, and the agent/user reviews the change before updating (skip with `--no-update-check`). `--doctor` additionally reports whether the available external scanners are on their latest version, but it never auto-upgrades system tools. These checks only query pinned official hosts over HTTPS (`raw.githubusercontent.com`/`api.github.com` for `decksoftware/csreview`, `pypi.org`, `crates.io`, `registry.npmjs.org`), never block the scan when offline, and never execute fetched content. - -**Opt-in security-tool provisioning (`--provision-tools`)**: CSReview's fidelity and low false-positive rate depend on running real stack-native security tools and corroborating them with the heuristic detector (a finding seen by both a tool and the detector is promoted to CONFIRMED). When the user opts in with `--provision-tools`, CSReview MAY install the tools it needs — but only safely, and the user is always informed before any download. It downloads each tool ONLY from its official release source (Gitleaks `github.com/gitleaks/gitleaks`, Trivy `github.com/aquasecurity/trivy`, gosec `github.com/securego/gosec`, Bandit from PyPI, plus the already-supported Semgrep and OSV-Scanner), VERIFIES the published SHA-256 checksum before the artifact is made executable or run (a mismatch or a non-official host is rejected, never executed), installs into an ISOLATED, gitignored `.csreview/bin/` workspace (never globally, never `sudo`, never as a project dependency, never modifying the audited source), and FAILS OPEN to lower-confidence Agent-Only mode when a tool cannot be provisioned (offline, unsupported platform, etc.). Without the flag, CSReview runs only tools already on the user's PATH and notes the rest as recommended. The report states which tools actually ran versus heuristic-only. - -**Stack-Native Tool Recommendation Matrix**: after detecting the languages, frameworks, package managers, and lockfiles in the workspace, CSReview MUST select the relevant read-only tools below. Run a tool only if it is already available in the user's environment, already configured in the workspace, or provisioned with explicit user opt-in (see Opt-in security-tool provisioning above). Do not install missing tools as project dependencies or into the global system, and never modify the audited source. If a recommended tool is unavailable and not provisioned, record it in the report as a `missing recommended tool` with the exact install/documentation pointer. These tools are agent-recommended unless listed under Engine-Orchestrated Tools. - -| Detected stack | Prefer read-only commands and scanners | -| --- | --- | -| JavaScript / TypeScript / React / Node | `npm audit --json` for npm lockfiles, `pnpm audit --json` for `pnpm-lock.yaml`, `npm run lint -- --format json` when configured, `eslint` with project config, `eslint-plugin-security`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `typescript-eslint`, Semgrep | -| .NET / C# / ASP.NET | `dotnet build --no-restore`, `dotnet format analyzers --verify-no-changes`, `dotnet package list --include-transitive --vulnerable --format json` or `dotnet list package --include-transitive --vulnerable --format json`, .NET Roslyn analyzers (`CAxxxx`, `IDExxxx`), Semgrep, CodeQL/default setup when available | -| Kotlin / Android / JVM | `gradlew lint` or `./gradlew lint`, Android Lint, `detekt`, `ktlint`, Qodana, Gradle dependency vulnerability checks, OSV-Scanner, Semgrep | -| Go | `go vet ./...`, `govulncheck ./...`, `gosec ./...`, `staticcheck ./...`, `golangci-lint run`, OSV-Scanner, Semgrep | -| Python | `pip-audit`, `bandit -r`, `ruff check`, `safety` when available, OSV-Scanner, Semgrep | -| Java / Spring / Maven / Gradle | Maven/Gradle dependency checks, SpotBugs/FindSecBugs when configured, Checkstyle/PMD when configured, Qodana, OSV-Scanner, Semgrep | -| Rust | `cargo audit`, `cargo deny check`, `cargo clippy --all-targets --all-features`, OSV-Scanner, Semgrep | -| PHP / Laravel / Symfony | `composer audit --format=json`, PHPStan/Psalm when configured, Laravel Pint for linting, OSV-Scanner, Semgrep | -| Ruby / Rails | `bundle audit`, `brakeman`, RuboCop when configured, OSV-Scanner, Semgrep | -| Flutter / Dart | `dart analyze`, `flutter analyze`, `dart pub outdated --json`, OSV-Scanner, Semgrep | -| IaC / containers / CI | Checkov, Trivy, Hadolint, Dockerfile linting, GitHub Actions linting, Terraform validators, Semgrep | -| BaaS / database rules | Supabase CLI checks when configured, Firebase rules validation when configured, Appwrite/Convex/PocketBase config review, SQL linters when configured, Semgrep | - -**External Research Protocol**: Do not guess when framework behavior, configuration defaults, security controls, exploitability, dependency advisories, CVE details, or remediation guidance are uncertain. The coding agent MUST know how to perform external internet research when necessary and MUST consult primary or specialized sources before reporting a confident recommendation: - -- official framework documentation, release notes, migration guides, and security pages -- Vendor security advisory pages for the affected product, cloud service, database, BaaS, or package manager -- OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, Snyk advisory pages, and other specialized application security portals -- Official package, API, or SDK documentation for the exact version or major version in use - -When external research is used, include source names and URLs in the finding references. Prefer official documentation and vendor advisories over generic blog posts. If sources disagree or the version cannot be confirmed, mark the finding as lower confidence and explain the uncertainty in the report. - -**No-Findings Assurance Limit**: A report with zero findings is not proof that the system is secure. It only means CSReview and the available external tools did not detect reportable issues in the analyzed scope. The HTML and Markdown reports MUST state this limitation when no findings are found. +CSReview is a white-hat security alignment tool (MIT License). Use it for authorized security reviews, local development hardening, education, and remediation. Do not use it to support unauthorized intrusion, exploitation, credential theft, data exfiltration, surveillance, or harm. CSReview is a Deck Software project idealized by Márcio PS, built with assistance and review from AI coding agents including Claude Code, Trae, MiniMax, Qwen, Cascade, Codex, GLM, MiMo, and other reviewer agents. -**Report Handoff Protocol**: After every CSReview run, the agent MUST present two explicit paths: +## Core Rules -- **Agent name prefix**: report filenames MUST begin with the coding agent name in lowercase, for example `codex_security-report.html` and `codex_security-findings.md`. Other agents must replace `codex` with their own name, such as `claude_security-report.html`. -- **MUST NOT generate generic report names**: `security-report.html`, `security-findings.md`, `_security-report.html`, `_security-findings.md`, `csreview-report.html`, and `csreview-report.md` are invalid handoff names because they hide which agent produced the analysis. -- **CLI identity**: pass `--agent-name ` on CLI runs or set `CSREVIEW_AGENT_NAME=` before running CSReview. Examples: `csreview . --agent-name codex`, `csreview . --agent-name claude`, `CSREVIEW_AGENT_NAME=qwen csreview .`. -- **HTML report path**: the absolute path to `csreview-reports/codex_security-report.html` or the configured output HTML file. Tell the user this is the file to click/open in a browser for human reading. If the environment has an available browser-opening tool and the user asked to open it, open the HTML report in the browser. -- **Markdown report path**: the absolute path to `csreview-reports/codex_security-findings.md` or the configured output Markdown file. Tell the user and the coding agent that this is the file the coding agent must analyze before planning any remediation. +These rules appear once, here, and apply everywhere: -The coding agent must not infer findings from the verbal summary alone. For remediation work, it must read the Markdown report path first, then inspect the referenced source files, framework documentation, schemas, tests, and security advisories before proposing or applying changes. +1. **READ-ONLY**: CSReview never modifies, deletes, moves, or creates source code in the analyzed project. It identifies problems, locates them precisely, and suggests remediation. Fixes are applied later by the developer or a coding agent with project context. Report files under the output directory and the gitignored `.csreview/` tool cache are audit artifacts, not source modifications. +2. **Global Skill Installation**: CSReview is a global agent skill, loaded from the agent's global skills environment (`~/.codex/skills/csreview`, `~/.agents/skills/csreview`, `~/.trae/skills/csreview`, `~/.claude/skills/csreview`). The agent MUST NOT copy, scaffold, install, update, delete, or move the CSReview skill inside the project being audited (including `/.claude/skills/`, `/AGENTS.md`, `/CLAUDE.md`, `.cursorrules`, `.windsurfrules`) unless the user explicitly asks for project-local installation. +3. **Single writer**: the engine writes the final reports. Subagents (when used) write only partial JSON. The agent never handcrafts report files. +4. **No fabricated metrics**: the engine does not compute ASVS coverage percentages, SLSA levels, or per-article compliance verdicts — so the agent must never state them as scan output. Compliance fields are CWE correlation (indicative), not an audited compliance verification. See `reference/compliance-frameworks.md`. +5. **Never expose secrets in chat**: hardcoded credentials found during a scan are referenced in the reports (redacted) — never echoed in the conversation. +6. **No-Findings Assurance Limit**: zero findings is not proof of security; it only means CSReview and the available tools detected nothing reportable in the analyzed scope. Reports state this; so must the agent. +7. **Honest confidence**: every claim carries its source (engine mode, tool, heuristic confidence). When uncertain, research (see External Research Protocol) or say the uncertainty out loud. -**Phase 9: Optional Local DAST Complementary Report**: after the user or coding agent has implemented and validated remediations from the static CSReview report, the agent MUST inform the user that an optional broader local dynamic validation is available. This phase is not part of the default SAST/SCA run and MUST NOT start automatically. It is a conservative local HTTP probe (security headers + CORS checks), NOT a full penetration test; for active probing install and run a dedicated tool such as Nuclei against the confirmed local target. +## How to Run the Engine -The required user-facing prompt is: "Static remediation is complete. You can optionally run CSReview Phase 9 Local DAST in a local test environment only. Never use this against production. If the test uses a database copy, make sure the copy was made deliberately, stored in a secure local place, and sanitized or minimized where needed. This resource is for White Hat Hacker-style analysis and remediation of security flaws; it sends real HTTP requests only to localhost/127.0.0.1 and writes a complementary report. Do you want me to run it? (yes/no)" - -Phase 9 may proceed only when all of these are true: - -- The user gives explicit user confirmation. -- The user understands this is for a local test environment, never production, and that any database copy used for testing must be securely created, stored, and handled. -- The target URL is strictly `http://localhost:`, `https://localhost:`, `http://127.0.0.1:`, `https://127.0.0.1:`, or the IPv6 loopback `http://[::1]:` / `https://[::1]:`. -- The `.env`, `.env.local`, and `.env.development` pre-flight is advisory, not blocking: if an external host is referenced, it is surfaced as a `DAST-SUSPECTED` warning so you verify the local app under test does not proxy probe traffic to that host. A real development `.env` almost always references external services, so this warning by itself does not abort Phase 9; the hard guards below still apply. -- Redirects are not followed. If a response points to an external host, abort Phase 9 immediately. (This is a hard guard enforced in the engine.) -- The complementary reports are written only inside `csreview-reports/` as `csreview-reports/_local-dast-report.html` and `csreview-reports/_local-dast-findings.md`. A run ID is embedded in the report and, when provided, time-stamped history copies are also written inside `csreview-reports/` so re-running Phase 9 after remediation does not overwrite the previous run's evidence. A read-only per-backend local database dump guide (`_db-dump-guide.html`) is also generated to help prepare an isolated local copy before any database-level testing. - -The CLI form is: +The CLI is the canonical execution path — never reimplement its phases by hand: ```bash -csreview . --local-dast-url http://localhost:3000 --confirm-local-dast --agent-name codex +csreview --agent-name +csreview --doctor [target-directory] # tool availability + freshness, no scan +csreview --version ``` -Phase 9 output uses dynamic status labels: - -- `DAST-CONFIRMED`: dynamically reproduced with clear evidence, normally from a dedicated local DAST tool or an explicitly allowed endpoint test. -- `DAST-SUSPECTED`: anomalous local response that requires human review. -- `DAST-CLEAN`: the checked condition passed for the local target. - -Hard limits: never probe external IPs, domains, staging, or production; never follow redirects to external hosts; never write outside `csreview-reports/`; never use destructive payloads; never use DELETE; do not send mutating POST/PUT/PATCH requests unless the user provided an explicit local test endpoint allowlist and confirmed the data mutation risk. The built-in CSReview local DAST mode is conservative and performs non-mutating HTTP checks such as reachability, browser security headers, and CORS behavior. OWASP ZAP or Nikto may be used only when installed, only after the same pre-flight checks and confirmation, and only against the confirmed local target. - -The analysis covers 8 default report sections: Reconnaissance, Ultra-Deep Security, Database Security, SLSA Build L3 (v1.2) Supply Chain, OWASP ASVS 5.0.0, Compliance mapping (LGPD/GDPR/SOC2/HIPAA/CCPA-CPRA — indicative correlation, not an audited compliance verification), Vibe Coding Protection, and Dual Report Generation. These are report sections, not separate executable engine phases. Phase 9 is optional, local-only, post-remediation, and produces a complementary report. - -CSReview includes built-in **Code Review** capabilities (equivalent to codex:review, codex:adversarial-review, code-review, requesting-code-review, receiving-code-review) - no additional skills or plugins required. - -## When to Invoke - -- User requests security review or code audit -- User asks for vulnerability scan or pentest analysis -- User wants to check for data leakage or exposed secrets -- User mentions SQL injection, XSS, auth flaws, or security concerns -- Before release or deployment preparation, while reviewing only the local workspace -- User asks to review Supabase, Firebase, Appwrite, Neon, or similar backend security -- User invokes `@csreview` or mentions CSReview -- User wants compliance verification (LGPD, GDPR, SOC 2, HIPAA) -- User built code with AI agents and wants to verify security (vibe coding check) -- User wants database structure security validation (SQL/NoSQL/BaaS) -- User requests code review (`@csreview review [files]`) -- User requests adversarial review (`@csreview adversarial [files]`) -- User requests security-focused review (`@csreview security-review [files]`) -- User wants to review changes in a PR or branch (`@csreview request-review [scope]`) -- User wants a remediation plan from a report (`@csreview review csreview-reports/codex_security-findings.md`) - -## Supported Technologies - -### Languages & Frameworks -- **Frontend**: React, Vue, Nuxt, Angular, Svelte, Next.js -- **Mobile**: Flutter, Kotlin (Android), Swift (iOS), React Native -- **Backend**: Python, Node.js, C#, Go, Java, PHP, Ruby -- **Systems**: C, C++, Rust -- **Desktop**: Electron, Tauri, native apps -- **.NET Ecosystem**: .NET Framework, .NET Core, .NET 5/6/7/8/9, ASP.NET Core, Blazor, MAUI, WPF, WinForms, Xamarin -- **Delphi/Lazarus**: Delphi (VCL, FMX), Lazarus (LCL), Free Pascal, Object Pascal -- **Go**: Go standard library, Gin, Echo, Fiber, GORM, and Go modules - -### Installer & Binary Security -- **DLL Analysis**: DLL hijacking, side-loading, missing ASLR/DEP, unsigned DLLs, export table inspection -- **Installers**: Inno Setup, NSIS, WiX, InstallShield, MSI packages, custom installers -- **Binary Security**: Code signing verification, Authenticode, checksum integrity, obfuscation review -- **Package Formats**: NuGet (.nupkg), Chocolatey, WinGet, DEB, RPM, APK, IPA, DMG - -### Databases & Backends -- **SQL**: PostgreSQL, MySQL, MariaDB, SQL Server, Firebird, SQLite, Oracle -- **NoSQL**: MongoDB, Redis, CouchDB, DynamoDB, Cassandra, ArangoDB -- **BaaS**: Supabase, Firebase, Appwrite, AWS Amplify, Nhost, Neon, PocketBase, Convex, PlanetScale, Turso - -### Operating Systems -- **macOS**: App Sandbox, Keychain, TCC, plists, XPC, Gatekeeper -- **iOS**: URL schemes, Keychain, jailbreak detection, TLS, ATS, biometrics -- **Linux**: SUID/SGID, cron, systemd, sudoers, containers, kernel modules -- **Windows**: Registry, UAC, COM, DLL hijacking, named pipes, services, ACLs - -### AI Agent Compatibility - -This skill is designed to work across multiple AI coding agents: - -| Agent | Integration Method | -|-------|-------------------| -| **Trae / SOLO** | Global skill via `~/.trae/skills/csreview/SKILL.md` | -| **OpenCode** | Compatible via global agent instructions | -| **Qwen CLI** | Compatible via system prompt injection | -| **Codex** | Global skill via `~/.codex/skills/csreview/SKILL.md` or `~/.agents/skills/csreview/SKILL.md` | -| **Claude Code** | Global skill via `~/.claude/skills/csreview/SKILL.md` | -| **Antigravity** | Compatible via global agent configuration | -| **Qoder** | Compatible via agent configuration | -| **Cursor / Windsurf / Cline** | Compatible via global rules/instructions when supported | -| **GitHub Copilot CLI** | Compatible via global/custom instructions when supported | -| **Aider / Continue / DevChat** | Compatible via global agent conventions when supported | - -**Cross-Agent Behavior**: Regardless of which agent invokes this skill, the analysis depth, report format, and vulnerability detection remain consistent. The HTML report is always generated in the user's language; the MD report is always in English for agent consumption. - -## Analysis Phases - -### Scatter-Gather Security Subagent Orchestration - -When the coding-agent runtime supports subagents and the workspace is large enough to justify the extra token/runtime cost, CSReview MAY ask the coding agent to use a scatter-gather workflow. This is an orchestration rule for agent reasoning, not a replacement for the deterministic npm engine. - -The dependency graph is: +Key options (run `csreview --help` for the full list): -1. **Phase 0 + Phase 1 sequential gate**: first detect tools, run the engine-orchestrated SAST/SCA tools once, scan the local workspace, and build the shared project map (`techStack`, frameworks, package managers, BaaS files, database files, IaC files, routes, and generated tool JSON). -2. **Compatibility-gated fan-out**: spawn only the subagents that match the map. Examples: do not spawn a Delphi subagent without Pascal/Delphi files; do not spawn a Firebase subagent without Firebase rules/config; do not spawn a Go subagent without Go modules/files. -3. **Parallel validation**: compatible subagents validate candidate findings in their domain by reading the shared map, relevant local files, and cached tool output. They must not rerun heavy SAST/SCA tools across the whole tree. -4. **Gather barrier**: wait for all subagents to finish before ASVS/compliance correlation. -5. **Reduce/correlation**: one coordinator merges all partial findings, then runs `dedup -> ASVS -> compliance -> score -> report` in that order. -6. **Single writer**: Subagents MUST NOT write final reports. They may write only partial JSON to `csreview-reports/.partials/.json`. The coordinator is the only writer for `_security-report.html` and `_security-findings.md`, and partial files must use the canonical finding schema. - -Hard rules: - -- If subagents are unavailable, too expensive for the repository size, or not supported by the current agent, fallback to sequential analysis. -- Run SAST/SCA tools once in the gate stage; later subagents consume cached tool output instead of rerunning Semgrep, OSV-Scanner, Node package audit, Trivy, or similar whole-tree scans. -- Every subagent finding must use the canonical finding schema (`id`, `severity`, `category`, `name`, `description`, `file`, `line`, `vulnerableCode`, `cwe`, `owasp`, `fix`, `confidence`, `exploitation`, `references`, `source`). Use `source: "subagent:"`, for example `source: "subagent:auth"`, so the coordinator can correlate and deduplicate against `csreview-detector`, `semgrep`, `npm-audit`, and `osv-scanner`. -- Subagents do not write final reports and do not modify audited source code. -- The coordinator owns final deduplication. Matching `file:line:CWE` evidence from multiple sources can be promoted to `CONFIRMED`. - -#### Subagent Orchestration DoD - -1. **Single writer**: Subagents MUST NOT write final reports. Each subagent writes only partial findings JSON to its own scratch file, for example `csreview-reports/.partials/.json`. The coordinator is the only writer for `_security-report.html` and `_security-findings.md`. -2. **Canonical schema**: every subagent finding uses the engine finding object (`severity`, `category`, `file`, `line`, `cwe`, `confidence`, `fix`, and related fields) and sets `source: "subagent:"`. Without this, `deduplicateFindings` cannot correlate evidence or promote confidence to `CONFIRMED`. -3. **Tool runs once**: Semgrep, Node package audit, OSV-Scanner, Trivy, and similar whole-tree SAST/SCA tools run only during Phase 0/1. Their JSON output is cached, and subagents read the cache instead of re-executing tools on the tree. -4. **Compatibility-gated fan-out**: spawn a subagent only when Phase 1 detected its stack, framework, or ruleset. Do not spawn technology-specific subagents for absent ecosystems. -5. **Barrier before reduce**: ASVS mapping, compliance mapping, and score calculation run only after all partial findings have returned. The coordinator applies `dedup -> ASVS -> compliance -> score -> report`. - -**Final check**: CSReview produces one pair of final reports, the final count matches the sum of partial findings after deduplication, and no tool appears executed more than once in the log. - -**Engine enforcement**: when `csreview-reports/.partials/` exists, the npm engine reads canonical partial JSON, merges valid `source: "subagent:"` findings into the final finding set, exposes `partialReconciliation`, and provides `reconcilePartials(outputDir, finalFindings, { strict: true })` for coordinators that need the run to fail when the DoD does not reconcile. - -#### Non-negotiable rules - -1. **Single writer**: subagents write partial JSON only; the coordinator writes final reports. -2. **Canonical schema**: subagent findings must use the engine finding object and `source: "subagent:"`. -3. **Tool runs once**: whole-tree SAST/SCA tools run in Phase 0/1 only; subagents read cached JSON. - -### Phase 0: Security Tool Detection & Integration - -**This is the FIRST step of every analysis.** CSReview MUST detect which security tools are available on the user's operating system and use them for real file-by-file scanning. When real tools are not available, CSReview falls back to AI-based analysis (which is less thorough). - -#### 0.0 Analysis Modes - -CSReview operates in three modes. These mode names are based on the deterministic npm engine's orchestrated tools, not on every agent-recommended tool listed in this skill. - -**Mode A: Self-Hosted (RECOMMENDED)** -- All relevant engine-orchestrated tools are available locally: Semgrep, OSV-Scanner, and the Node package audit selected by lockfile (`pnpm audit` for `pnpm-lock.yaml`, `npm audit` for npm lockfiles). -- CSReview detects, invokes, parses, deduplicates, and scores these deterministic outputs. -- Findings from parsed tools are reproducible and can become `TOOL-ONLY` or `CONFIRMED` when matching CSReview detector evidence. -- Agent-recommended stack-native tools may still be listed as missing or supplemental; they do not change the engine mode unless their outputs are parsed by the npm engine. -- **This is the highest-confidence CSReview engine mode for local workspace analysis.** - -**Mode B: Agent-Only (FALLBACK)** -- No engine-orchestrated tool is available. -- CSReview relies on local scanner metadata plus regex/static heuristics and any careful agent reading of local files. -- **WARNING**: This mode has lower precision and recall. Line-oriented regex checks can miss multiline issues and may report false positives. -- Always clearly mark the run lower confidence and recommend installing Semgrep and OSV-Scanner before relying on the result. - -**Mode C: Hybrid (PARTIAL)** -- Some, but not all, relevant engine-orchestrated tools are available. -- CSReview runs available parsed tools and supplements them with detector heuristics and agent review. -- Tool findings are marked `TOOL-ONLY`; detector+tool agreement is deduplicated and promoted to `CONFIRMED`. -- Missing relevant tools must be disclosed in the report. - -**The agent MUST inform the user which mode is active and what the implications are.** - -#### 0.1 Tool Detection Protocol +| Option | Purpose | +| --- | --- | +| `--agent-name ` | Prefix report files with the coding agent name (or set `CSREVIEW_AGENT_NAME`) | +| `--output, -o ` | Output directory (default `/csreview-reports/`) | +| `--fail-on ` | CI gate: exit 1 when findings at or above `critical\|high\|medium\|low` remain | +| `--baseline ` / `--update-baseline` | Suppress known findings so CI fails only on NEW ones | +| `--provision-tools` | Opt-in: run Gitleaks/Trivy/gosec/Bandit; missing ones are downloaded from OFFICIAL releases, SHA-256-verified, into gitignored `.csreview/bin/` | +| `--tool-timeout ` | Per-tool timeout in seconds (default 120); timeouts are reported as timeouts, not as missing tools | +| `--semgrep-config ` | Use local/explicit Semgrep rules instead of `auto` (offline-friendly; adds `--metrics=off`) | +| `--local-dast-url ` + `--confirm-local-dast` | Phase 9 local-only dynamic complement (see below) | +| `--strict-partials` | Fail when subagent partials do not reconcile | +| `--no-update-check` | Skip the read-only, fail-open self-update advisory | -At the start of every scan, run detection commands for each tool. Use `RunCommand` or equivalent: +A `.csreview-ignore` file at the project root (gitignore-style globs) suppresses findings for matching paths in the report only. Unknown CLI flags are hard errors by design — a mistyped option aborts instead of silently changing what is audited. -#### 0.1.1 Engine-Orchestrated Tools +### Engine-Orchestrated Tools -These are the tools the npm engine currently invokes and parses deterministically: +The engine invokes and parses these deterministically; their findings enter deduplication and scoring: | Tool | Engine behavior | |------|-----------------| -| Semgrep | Runs `semgrep --config auto --json --quiet ` and parses findings | -| Node package audit | Runs `pnpm audit --json` when `pnpm-lock.yaml` exists, otherwise `npm audit --json` for npm lockfiles, and parses dependency findings | -| OSV-Scanner | Runs `osv-scanner scan --format json ` and parses dependency findings | -| Local DAST | Optional post-remediation local-only complement via `--local-dast-url`, writing separate reports | - -#### 0.1.2 Agent-Recommended Stack-Native Tools - -The tools below are recommended for agent-assisted validation when relevant to the detected stack. They are not parsed by the npm engine unless explicitly listed under Engine-Orchestrated Tools, so their results must be reported as supplemental evidence rather than silently merged into engine counts. - -**Detection Commands:** -```bash -# Semgrep - Multi-language static analysis (MANDATORY baseline attempt) -semgrep --version -# Required scan when available: semgrep --config auto --json --quiet - -# OSV-Scanner - Multi-ecosystem dependency vulnerability scanning -osv-scanner --version -# If found: osv-scanner scan --format json +| Semgrep | **Mandatory baseline attempt** on every run: `semgrep --config auto --json --quiet ` (or `--semgrep-config `). If unavailable or timed out, the run is marked lower confidence with install instructions (`pipx install semgrep`). | +| Node package audit | Selected by lockfile: `pnpm audit --json` for `pnpm-lock.yaml`, `npm audit --json` for npm lockfiles, `bun audit --json` for `bun.lock`/`bun.lockb` | +| OSV-Scanner | `osv-scanner scan --format json ` for multi-ecosystem dependency vulnerabilities | +| Gitleaks / Trivy / gosec / Bandit | Only with `--provision-tools` (Bandit only if already installed); results corroborate the detector | +| Built-in detector | Heuristic patterns for secrets (redacted in evidence), config/IaC/BaaS misconfigurations (scoped to config-kind files), and common vulnerability shapes | +| Local DAST | Optional Phase 9 complement via `--local-dast-url`, separate reports | -# Bandit - Python security linter -bandit --version -# If found: bandit -r -f json -ll +### Analysis Modes -# Trivy - Vulnerability scanner (dependencies, containers, IaC) -trivy --version -# If found: trivy fs --format json --output report.json +The engine reports which mode ran; the agent MUST tell the user and what it implies: -# CodeQL - GitHub's semantic code analysis (if qlpack available) -codeql version -# If found: codeql database create / analyze +- **Mode A: Self-Hosted (RECOMMENDED)** — all relevant engine-orchestrated tools are available; parsed, reproducible findings; highest-confidence engine mode. +- **Mode B: Agent-Only (FALLBACK)** — no engine-orchestrated tool available; regex/static heuristics plus careful agent reading. Lower precision and recall; line-oriented checks miss multiline issues. Mark the run lower confidence and recommend installing Semgrep and OSV-Scanner. +- **Mode C: Hybrid (PARTIAL)** — some tools available; missing ones are disclosed in the report. -# ESLint with security plugins -npx eslint --version 2>/dev/null || eslint --version -# If found: npx eslint --ext .js,.ts,.jsx,.tsx --config .eslintrc.security.json +### Agent-Recommended Stack-Native Tools -# Snyk - Dependency vulnerability scanning -snyk --version -# If found: snyk test --json > report.json +Tools below are recommended for agent-assisted validation when relevant to the detected stack. They are **not parsed by the npm engine**: report their results as supplemental evidence, never silently merged into engine counts. Run a tool only if already available, already configured in the workspace, or provisioned with explicit user opt-in; do not install missing tools into the analyzed project or globally. If a relevant tool is unavailable, record it in the report as a `missing recommended tool` with the install pointer (see `reference/tooling.md` for detection, invocation, and installation commands). -# SonarQube Scanner -sonar-scanner --version 2>/dev/null -# If found: sonar-scanner -Dsonar.projectKey=... -Dsonar.sources=. +#### Stack-Native Tool Recommendation Matrix -# Safety - Python dependency vulnerability checker -safety --version -# If found: safety check --json +| Detected stack | Prefer read-only commands and scanners | +| --- | --- | +| JavaScript / TypeScript / React / Node | lockfile-selected package audit (engine), configured `eslint`, `eslint-plugin-security`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `typescript-eslint`, Semgrep | +| .NET / C# / ASP.NET | `dotnet format analyzers --verify-no-changes`, `dotnet list package --include-transitive --vulnerable --format json`, Roslyn analyzers, Semgrep, CodeQL when available | +| Kotlin / Android / JVM | `gradlew lint` or `./gradlew lint`, Android Lint, `detekt`, `ktlint`, Qodana, Gradle dependency checks, OSV-Scanner, Semgrep | +| Go | `go vet ./...`, `govulncheck ./...`, `gosec ./...`, `staticcheck ./...`, `golangci-lint run`, OSV-Scanner, Semgrep | +| Python | `pip-audit`, `bandit -r`, `ruff check`, `safety` when available, OSV-Scanner, Semgrep | +| Java / Spring / Maven / Gradle | Maven/Gradle dependency checks, SpotBugs/FindSecBugs when configured, Checkstyle/PMD when configured, Qodana, OSV-Scanner, Semgrep | +| Rust | `cargo audit`, `cargo deny check`, `cargo clippy --all-targets --all-features`, OSV-Scanner, Semgrep | +| PHP / Laravel / Symfony | `composer audit --format=json`, PHPStan/Psalm when configured, OSV-Scanner, Semgrep | +| Ruby / Rails | `bundle audit`, `brakeman`, RuboCop when configured, OSV-Scanner, Semgrep | +| Flutter / Dart | `dart analyze`, `flutter analyze`, `dart pub outdated --json`, OSV-Scanner, Semgrep | +| IaC / containers / CI | Checkov, Trivy, Hadolint, Dockerfile linting, GitHub Actions linting, Terraform validators, Semgrep | +| BaaS / database rules | Supabase CLI checks when configured, Firebase rules validation when configured, Appwrite/Convex/PocketBase config review, SQL linters when configured, Semgrep | -# Gosec - Go security linter -gosec --version -# If found: gosec -fmt json -out report.json ./... +## External Research Protocol -# Grype - Vulnerability scanner for container images and filesystems -grype version -# If found: grype dir: -o json +Do not guess when framework behavior, configuration defaults, security controls, exploitability, dependency advisories, CVE details, or remediation guidance are uncertain. Consult primary or specialized sources before reporting a confident recommendation: -# Hadolint - Dockerfile security linter -hadolint --version -# If found: hadolint Dockerfile --format json +- official framework documentation, release notes, migration guides, and security pages +- vendor security advisory pages for the affected product, cloud service, database, BaaS, or package manager +- OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, Snyk advisories, and other specialized application security portals +- official package, API, or SDK documentation for the exact version in use -# TFLint - Terraform linter -tflint --version -# If found: tflint --format json +Include source names and URLs in finding references. Prefer official documentation and vendor advisories over blog posts. If sources disagree or the version cannot be confirmed, mark the finding lower confidence and explain the uncertainty. -# Checkov - Infrastructure-as-code security -checkov --version -# If found: checkov -d -o json +## Execution Workflow -# Brakeman - Ruby on Rails security scanner -brakeman --version -# If found: brakeman --format json -o report.json +1. **Confirm global skill scope** (Core Rule 2) if the task involves installing or updating CSReview itself. +2. **Announce the scan** and run the engine: `csreview --agent-name ` (plus `--provision-tools` when the user opted in, `--baseline` when one exists). The engine performs tool detection, the tool runs, workspace discovery, heuristic detection, deduplication, scoring, and report generation. +3. **Report the mode** (Self-Hosted / Hybrid / Agent-Only) and which tools ran, were skipped, or timed out — exactly as the engine printed them. +4. **Contextual review pass**: read the Markdown report, then inspect the flagged files and their surroundings using the checklists in `reference/security-checklists.md` (injection, auth, data leakage, BaaS rules, platform-specific surfaces, database security, Firebase cost patterns). Validate or discount engine findings with file-level context; research anything uncertain (External Research Protocol). +5. **Supply-chain and compliance correlation** when the user asked for it: use `reference/compliance-frameworks.md` (SLSA Build L3 (v1.2) checklist, OWASP ASVS 5.0.0 areas, LGPD/GDPR/SOC2/HIPAA/CCPA-CPRA) — correlation and judgment, never fabricated percentages. +6. **Vibe Coding Heuristics**: the engine attaches a `vibeRisk` flag — a static boolean heuristic marking vulnerability patterns that commonly appear in rushed or AI-assisted code. It does not prove AI authorship and is a prioritization hint, nothing more. +7. **Deliver the reports** (Report Handoff Protocol below) and a verbal summary of CRITICAL/HIGH findings, tool-detected vs heuristic-only counts, and disclosed gaps. +8. **Offer next steps**: a prioritized remediation plan, or a coding-agent session to apply selected fixes with project-context validation, then a re-run (optionally `--update-baseline` after triage, `--fail-on high` in CI). +9. **Offer Phase 9** (optional local DAST) only after remediation work. -# RetireJS - JavaScript library vulnerability scanner -retire --version -# If found: retire --path --outputformat json +The default report covers 8 sections: Reconnaissance, Ultra-Deep Security, Database Security, SLSA Build L3 (v1.2) Supply Chain, OWASP ASVS 5.0.0, Compliance mapping (LGPD/GDPR/SOC2/HIPAA/CCPA-CPRA — indicative correlation, not an audited compliance verification), Vibe Coding Protection, and Dual Report Generation. These are report sections, not separate executable engine phases. -# OWASP Dependency-Check -dependency-check.sh --version 2>/dev/null || dependency-check --version 2>/dev/null -# If found: dependency-check --project --scan --format JSON +## Report Handoff Protocol -# pip-audit - Python dependency auditing -pip-audit --version -# If found: pip-audit --format json +After every CSReview run, the agent MUST present two explicit paths: -# cargo-audit - Rust dependency auditing -cargo audit --version -# If found: cargo audit --json +- **Agent name prefix**: report filenames MUST begin with the coding agent name in lowercase, for example `codex_security-report.html` and `codex_security-findings.md`. Other agents replace `codex` with their own name, such as `claude_security-report.html`. Pass `--agent-name ` or set `CSREVIEW_AGENT_NAME=`. +- **MUST NOT generate generic report names**: `security-report.html`, `security-findings.md`, `csreview-report.html`, and similar agent-less names are invalid handoff names because they hide which agent produced the analysis. +- **HTML report path**: the absolute path to `csreview-reports/codex_security-report.html` (or configured output). Tell the user this is the file to open in a browser for human reading; if a browser-opening tool is available and the user asked, open it. +- **Markdown report path**: the absolute path to `csreview-reports/codex_security-findings.md`. The coding agent must analyze this file before planning any remediation — never infer findings from the verbal summary alone. For remediation work, read the Markdown report first, then inspect the referenced source files, framework documentation, schemas, tests, and security advisories before proposing changes. +- **SARIF path**: `csreview-reports/codex_security.sarif` for CI / GitHub code scanning ingestion (no raw vulnerable code embedded). -# npm audit (always available with npm) -npm --version -# If found: npm audit --json +## Finding Semantics -# pnpm audit (selected when pnpm-lock.yaml exists) -pnpm --version -# If found: pnpm audit --json +Confidence labels (engine-emitted): `CONFIRMED` (corroborated by independent sources at the same file:line:CWE), `TOOL-ONLY` (one external tool), `HIGH`/`MEDIUM`/`LOW` (heuristic detector confidence; non-source paths such as tests/fixtures are downgraded to LOW). Exploitation text in findings is always a **Potential Exploitation Path (theoretical, unverified)** — a hypothesis derived from static analysis, not a validated or executed exploit. Full report anatomy and the canonical finding schema: `reference/reports.md`. -# yarn audit -yarn --version -# If found: yarn audit --json +Severity classification: -# dotnet list package --vulnerable (always available with dotnet) -dotnet --version -# If found: dotnet list package --vulnerable --include-transitive -``` +| Severity | Criteria | Response | +|----------|----------|----------| +| **CRITICAL** | Direct data breach, RCE, auth bypass, exposed PII/secrets | Immediate fix | +| **HIGH** | Significant vulnerability, exploitable with effort | 24-48h | +| **MEDIUM** | Moderate risk, requires specific conditions | Within a week | +| **LOW** | Minor issue, defense-in-depth | Next sprint | +| **INFO** | Best-practice recommendation | Consider | -#### 0.2 Tool Selection Matrix - -After detection, select tools based on detected project languages: - -| Language/Framework | Primary Tools | Secondary Tools | -|-------------------|---------------|-----------------| -| **JavaScript/TypeScript** | semgrep, eslint (security), npm audit or pnpm audit selected by lockfile, osv-scanner | snyk, retire | -| **Python** | bandit, safety, pip-audit, osv-scanner | semgrep, snyk | -| **Go** | gosec, govulncheck, trivy, osv-scanner | semgrep | -| **C# / .NET** | dotnet list package --vulnerable, osv-scanner | semgrep, snyk | -| **Java** | semgrep, snyk, OWASP dep-check, osv-scanner | trivy | -| **Ruby** | brakeman, bundler-audit | semgrep | -| **Rust** | cargo audit, osv-scanner | semgrep, trivy | -| **PHP** | semgrep, snyk | psalm (security) | -| **Kotlin/Swift** | semgrep, snyk | trivy | -| **Docker** | hadolint, trivy, grype | checkov | -| **Terraform/IaC** | checkov, tflint, trivy | semgrep | -| **Delphi/Lazarus** | AI-based analysis only | semgrep (if available) | -| **Multi-language** | semgrep, osv-scanner, trivy | snyk, grype | - -#### 0.3 Execution Strategy - -**When real tools ARE available:** -1. Run all applicable tools in parallel (use `RunCommand` with `blocking: false` for each) -2. Collect JSON output from each tool -3. Parse and normalize findings into unified format -4. Merge with AI-based analysis (Phase 1-7) for comprehensive coverage -5. Deduplicate findings (same file+line+type = same issue) -6. Prioritize: tool findings take precedence over AI-only findings - -**When real tools are NOT available:** -1. Inform the user: "No security scanning tools detected. Using AI-based analysis only. For better accuracy, install: [recommended tools for their stack]" -2. Run AI-based analysis (Phase 1-7) with enhanced depth -3. Add a disclaimer to reports: "This report was generated using AI-based analysis only. For production security audits, install and run: semgrep, [language-specific tool]" -4. Still generate both HTML and MD reports, but mark findings with confidence level - -**Confidence Levels:** -| Level | Source | Description | -|-------|--------|-------------| -| **CONFIRMED** | Real tool + AI agree | Highest confidence - both tool and AI identified the issue | -| **TOOL-ONLY** | Real tool only | Issue found by tool but not confirmed by AI review | -| **AI-ONLY** | AI analysis only | Issue found by AI but not detected by tools | -| **AI-ESTIMATED** | No tools available | AI-based analysis only, lower confidence | - -#### 0.4 Tool Output Normalization - -Each tool's output must be normalized into this unified format: - -```json -{ - "source": "semgrep|bandit|trivy|snyk|eslint|codeql|gosec|...", - "id": "unique-finding-id", - "severity": "CRITICAL|HIGH|MEDIUM|LOW|INFO", - "category": "injection|xss|auth|config|dependency|...", - "file": "relative/path/to/file", - "line": 42, - "column": 10, - "title": "Short description", - "description": "Detailed description", - "cwe": "CWE-89", - "confidence": "CONFIRMED|TOOL-ONLY|AI-ONLY|AI-ESTIMATED", - "fix": "Suggested fix or remediation", - "references": ["url1", "url2"], - "tool_metadata": { - "rule_id": "semgrep-rule-id", - "owasp_category": "A03:2021", - "cve": "CVE-2024-XXXX" - } -} -``` +## Scatter-Gather Security Subagent Orchestration -#### 0.5 Per-Tool Invocation Details +When the agent runtime supports subagents and the workspace is large enough to justify the cost, CSReview MAY use a scatter-gather workflow; otherwise fallback to sequential analysis. The flow is: **Phase 0 + Phase 1 sequential gate** (engine run + shared project map) → **compatibility-gated fan-out** (spawn only subagents matching detected stacks) → parallel validation against cached tool output → gather barrier → reduce (`dedup -> ASVS -> compliance -> score -> report`). -**Semgrep (highest priority - multi-language):** -```bash -# Auto-detect rules from registry -semgrep --config auto --json --quiet --no-git-ignore +### Subagent Orchestration DoD -# With specific rulesets -semgrep --config p/security-audit --config p/secrets --config p/owasp-top-ten --json -``` +1. **Single writer**: Subagents MUST NOT write final reports. Each writes only partial findings JSON to `csreview-reports/.partials/.json`; the coordinator is the only writer of the final reports. +2. **Canonical finding schema**: every partial finding uses the engine finding object and sets `source: "subagent:"` — without it the engine cannot correlate evidence or promote to `CONFIRMED`. +3. **Run SAST/SCA tools once**: whole-tree tools (Semgrep, package audit, OSV-Scanner, Trivy) run only in the gate; subagents read cached tool output instead of re-executing them. -**Bandit (Python-specific):** -```bash -bandit -r -f json -ll -i --skip B101 -# -ll = medium and high severity only -# --skip B101 = skip assert warnings (too noisy) -``` +**Final check**: CSReview produces one pair of final reports, the final count matches the sum of partial findings after deduplication, and no tool appears executed more than once in the log. The engine enforces this via `partialReconciliation` (`--strict-partials` to fail hard). -**Trivy (comprehensive scanner):** -```bash -# Filesystem scan (dependencies + misconfigs) -trivy fs --format json --scanners vuln,misconfig,secret +### Non-negotiable rules -# With severity filter -trivy fs --severity HIGH,CRITICAL --format json -``` +1. Single writer — partial JSON only; the engine/coordinator writes reports. +2. Canonical schema with `source: "subagent:"`. +3. Whole-tree tools run once, in the gate. -**OSV-Scanner (multi-ecosystem dependency SCA):** -```bash -osv-scanner scan --format json -``` -- Parse JSON `results[].packages[].vulnerabilities[]` -- Map findings to OWASP A06: Vulnerable and Outdated Components -- Do not run `osv-scanner fix` or guided remediation during CSReview +Full protocol and partial-file contract: `reference/subagents.md`. -**Node package audit (Node.js dependencies):** -```bash -cd && npm audit --json # npm lockfiles -cd && pnpm audit --json # pnpm-lock.yaml -``` -- Parse npm `vulnerabilities` and pnpm `advisories` -- Do not run package-manager fix/update commands during CSReview - -**Snyk (if authenticated):** -```bash -snyk test --json --severity-threshold=medium -``` - -**Gosec (Go-specific):** -```bash -gosec -fmt json -out /tmp/gosec-report.json -severity medium ./... -``` +## Phase 9: Optional Local DAST Complementary Report -**dotnet (C#/.NET dependencies):** -```bash -dotnet list package --vulnerable --include-transitive -``` +Available only after the user or coding agent has implemented and validated remediations from the static report. It MUST NOT start automatically, and it is a conservative local HTTP probe (reachability, security headers, CORS), NOT a full penetration test. -**cargo audit (Rust):** -```bash -cargo audit --json -``` - -**pip-audit (Python dependencies):** -```bash -pip-audit --format json --desc -``` - -**Checkov (IaC security):** -```bash -checkov -d -o json --quiet --compact -``` - -**Hadolint (Dockerfile):** -```bash -hadolint /Dockerfile --format json -``` - -#### 0.6 Installation Recommendations +The required user-facing prompt is: "Static remediation is complete. You can optionally run CSReview Phase 9 Local DAST in a local test environment only. Never use this against production. If the test uses a database copy, make sure the copy was made deliberately, stored in a secure local place, and sanitized or minimized where needed. This resource is for White Hat Hacker-style analysis and remediation of security flaws; it sends real HTTP requests only to localhost/127.0.0.1 and writes a complementary report. Do you want me to run it? (yes/no)" -When tools are missing, provide platform-specific installation instructions: +Phase 9 may proceed only with explicit user confirmation, only for a local test environment, never production, and only against `http(s)://localhost:`, `http(s)://127.0.0.1:`, or `http(s)://[::1]:`. The engine enforces the hard guards: redirects are never followed — if a response points to an external host, abort Phase 9 immediately; reports are written only inside `csreview-reports/` (`csreview-reports/_local-dast-report.html`, `_local-dast-findings.md`, plus run-ID history copies and the read-only `_db-dump-guide.html`). ```bash -# Semgrep (all platforms) -pipx install semgrep -# Alternative: uv tool install semgrep - -# OSV-Scanner -# Windows: winget install Google.OSVScanner -# macOS/Linux: brew install osv-scanner -# Go: go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest - -# Bandit (Python) -pip install bandit - -# Trivy (all platforms) -# Windows: choco install trivy OR scoop install trivy -# macOS: brew install trivy -# Linux: sudo apt-get install trivy OR curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh - -# Snyk -npm install -g snyk - -# Gosec (Go) -go install github.com/securego/gosec/v2/cmd/gosec@latest - -# pip-audit -pip install pip-audit - -# cargo audit -cargo install cargo-audit - -# Checkov -pip install checkov - -# Hadolint -# Windows: choco install hadolint -# macOS: brew install hadolint -# Linux: docker pull hadolint/hadolint - -# ESLint Security Plugin -npm install --save-dev eslint-plugin-security eslint-plugin-no-unsanitized -``` - -### Phase 1: Reconnaissance & Mapping - -1. **Project Structure Scan** - - Identify all languages, frameworks, and dependencies - - Map entry points, API routes, and data flow paths - - Locate configuration files (.env, config.*, database.yml, etc.) - -2. **Secret Detection** - - Hardcoded API keys, tokens, passwords - - Connection strings with credentials - - Private keys, certificates, secrets in code - - Environment files committed to version control - -3. **External Service Mapping** - - Supabase: tables, RLS policies, edge functions, storage rules - - Firebase: database rules, storage rules, auth config - - Appwrite: collections, permissions, functions - - AWS/GCP/Azure: IAM roles, S3 buckets, exposed endpoints - -### Phase 2: Ultra-Deep Security Analysis - -#### 2.1 Injection Vulnerabilities -- **SQL Injection**: Raw queries, string concatenation, ORM misuse -- **NoSQL Injection**: MongoDB query injection, Redis command injection -- **Command Injection**: exec(), system(), subprocess calls with user input -- **LDAP Injection**: Directory service query manipulation -- **XPath Injection**: XML query manipulation -- **Template Injection**: SSTI in Jinja2, Twig, EJS, etc. - -#### 2.2 Authentication & Authorization -- **JWT Flaws**: Missing validation, weak secrets, algorithm confusion -- **Session Management**: Insecure cookies, missing HttpOnly/Secure flags -- **RLS Policies**: Missing or bypassable Row Level Security (Supabase) -- **Role-Based Access**: Privilege escalation, missing authorization checks -- **IDOR**: Insecure Direct Object References exposing other users' data -- **OAuth/OpenID**: Misconfigured flows, token leakage, redirect URI flaws - -#### 2.3 Data Leakage -- **Log Exposure**: Sensitive data in console.log, logger, error messages -- **Stack Traces**: Full error details exposed to users -- **PII Exposure**: Personal data in API responses without filtering -- **Debug Mode**: Debug endpoints or panels enabled in production -- **Response Headers**: Server version, framework info leakage -- **Cache Exposure**: Sensitive data cached in browser or CDN - -#### 2.4 Cross-Site Vulnerabilities -- **XSS**: Reflected, stored, DOM-based (dangerouslySetInnerHTML, v-html) -- **CSRF**: Missing tokens, SameSite cookie misconfiguration -- **CORS**: Overly permissive origins, wildcard Access-Control-Allow-Origin -- **Clickjacking**: Missing X-Frame-Options or CSP frame-ancestors - -#### 2.5 Insecure Configurations -- **Security Headers**: Missing CSP, HSTS, X-Content-Type-Options -- **TLS/SSL**: Weak ciphers, missing certificate pinning, HTTP fallback -- **File Uploads**: Missing validation, executable file upload, path traversal -- **Rate Limiting**: Missing brute force protection, API abuse vectors -- **Error Handling**: Verbose errors, information disclosure - -#### 2.6 Dependency Vulnerabilities -- **Outdated Packages**: Known CVEs in dependencies -- **Supply Chain**: Suspicious packages, typosquatting, compromised deps -- **License Compliance**: Restrictive licenses in production - -#### 2.7 Cloud & Backend Security -- **Supabase**: - - Missing RLS policies on sensitive tables - - Overly permissive policies (allow all authenticated) - - Exposed service role key in client code - - Storage bucket public access misconfiguration - - Edge function authentication bypass -- **Firebase**: - - Database rules allowing read/write to all users - - Storage rules without authentication checks - - Exposed API keys with excessive permissions - - Missing App Check enforcement -- **Appwrite**: - - Collection permissions too permissive - - Missing attribute validation - - Function execution without auth checks - -#### 2.8 Platform-Specific Vulnerabilities - -**macOS:** -- App Sandbox escape vectors -- Keychain insecure access patterns -- TCC (Transparency, Consent, Control) permission abuse -- Plist misconfigurations exposing sensitive data -- XPC service vulnerabilities -- Gatekeeper bypass vectors -- Insecure file permissions (world-readable/writable) - -**iOS:** -- Insecure URL scheme handling -- Keychain data exposure -- Missing jailbreak detection -- TLS certificate validation bypass -- UserDefaults storing sensitive data -- Biometric authentication flaws -- App Transport Security (ATS) disabled -- Screenshot/cache exposure of sensitive screens -- Insecure WKWebView configurations - -**Linux:** -- SUID/SGID binary vulnerabilities -- Cron job injection or race conditions -- Insecure systemd service configurations -- File permission escalation vectors -- Sudoers misconfigurations -- Exposed Unix sockets -- Kernel module vulnerabilities -- Container escape vectors (Docker, LXC) -- Insecure mount options - -**Windows:** -- Registry key exposure of sensitive data -- UAC bypass vectors -- Insecure COM object configurations -- DLL hijacking vulnerabilities -- Named pipe access control flaws -- Service account privilege escalation -- PowerShell execution policy bypass -- Insecure ACLs on files/directories -- Token impersonation flaws - -#### 2.9 Cross-Platform System Vulnerabilities -- **Path Traversal**: File operations with unsanitized paths -- **Symlink Attacks**: Following malicious symlinks -- **Environment Variable Injection**: Untrusted env var manipulation -- **Insecure Temp Files**: Predictable temp file names -- **Race Conditions**: TOCTOU in file/resource access -- **Memory Corruption**: Buffer overflow, use-after-free in native code -- **IPC Insecurity**: Unprotected inter-process communication -- **Credential Storage**: Plaintext passwords, tokens, keys - -#### 2.10 .NET / dotnet Security - -**ASP.NET Core / Blazor:** -- Missing `[Authorize]` attributes on controllers/pages -- CORS policy set to `AllowAnyOrigin` in production -- Missing anti-forgery tokens (`[ValidateAntiForgeryToken]`) -- Insecure cookie configuration (missing HttpOnly, Secure, SameSite) -- Sensitive data in `appsettings.json` without user secrets or key vault -- Missing rate limiting middleware -- Debug mode enabled in production (`ASPNETCORE_ENVIRONMENT=Development`) -- Missing HTTPS redirection and HSTS -- Insecure Data Protection API key storage -- Missing input validation with `[ValidateInput]` or FluentValidation - -**Entity Framework / EF Core:** -- Raw SQL queries with string interpolation (`FromSqlRaw` with unsanitized input) -- Missing parameterization in LINQ-to-SQL dynamic queries -- Lazy loading without `ProxyCreationEnabled` control (N+1 queries) -- Excessive `Include()` chains loading unnecessary related data -- Missing migration rollback scripts -- Connection strings with credentials in plain text -- Missing database connection encryption - -**NuGet / Package Security:** -- Packages from untrusted sources -- Missing `nuget.config` source restrictions -- Packages with known vulnerabilities (check against CVE database) -- Transitive dependency vulnerabilities -- Missing lock files (`packages.lock.json`) - -**.NET Binary Security:** -- Missing strong naming / signing of assemblies -- `AllowPartiallyTrustedCallers` attribute misuse -- Missing `[SecurityCritical]` / `[SecuritySafeCritical]` boundaries -- Reflection-based type loading from untrusted sources -- BinaryFormatter / SoapFormatter deserialization (known insecure) -- Missing `SecureString` usage for sensitive data in memory - -#### 2.11 Delphi / Lazarus Security - -**Delphi (VCL / FireMonkey):** -- Hardcoded database credentials in `.dpr` or `.pas` files -- Missing encryption for stored connection strings -- BDE (Borland Database Engine) insecure configurations -- dbExpress / FireDAC connection strings with plaintext passwords -- Insecure file operations (no path validation on user input) -- Missing input validation on TForm controls -- COM automation with late binding (variant-based) without safety checks -- Unsafe pointer operations and untyped `var` parameters -- Missing bounds checking on dynamic arrays and strings (`{$RANGECHECKS ON}`) -- Insecure registry operations (direct Windows Registry access without validation) -- Missing overflow checking (`{$OVERFLOWCHECKS ON}`) - -**Lazarus / Free Pascal:** -- Hardcoded credentials in `.lpr` or `.pas` source files -- SQLite databases without encryption (SQLite3 without SEE or sqlcipher) -- Missing parameterized queries in SQLdb components -- Insecure INI file configurations with sensitive data -- Missing TLS for network communications (Indy / Synapse without SSL) -- Form data stored without encryption -- Insecure file permissions on Linux deployments -- Missing `{$MODESWITCH ANSISTRINGS}` causing string handling issues -- Buffer overflows in `Move`, `FillChar`, `GetMem` operations -- Missing exception handling around database operations - -**Database Connectivity (Delphi/Lazarus):** -- Firebird/InterBase connection strings with embedded passwords -- Missing SSL/TLS for database connections -- Unencrypted `.fdb` / `.gdb` database files -- IBX / FIBPlus components with default credentials -- Missing `EXECUTE STATEMENT` parameterization in Firebird PSQL -- zeoslib connection pooling misconfigurations - -#### 2.12 Go Security - -**Web Frameworks (Gin, Echo, Fiber):** -- Missing input validation middleware -- SQL injection via `fmt.Sprintf` in queries instead of parameterized statements -- Missing CSRF protection -- Unbounded file uploads without size/type validation -- Missing rate limiting -- CORS middleware with `AllowAllOrigins: true` -- Missing request body size limits -- Error messages leaking internal state - -**Go-Specific Vulnerabilities:** -- `exec.Command` with unsanitized user input -- `os.ReadFile` / `ioutil.ReadFile` with user-controlled paths (path traversal) -- `template.HTML` bypassing auto-escaping -- `unsafe.Pointer` usage and CGo boundary vulnerabilities -- Missing bounds checking in slice operations -- Goroutine leaks (missing context cancellation) -- Race conditions from shared mutable state without `sync.Mutex` -- `json.Unmarshal` into `interface{}` without schema validation -- Missing `context.WithTimeout` for external service calls -- Hardcoded credentials in source code - -**Go Modules:** -- `go.sum` integrity verification failures -- Replaced modules (`replace` directive) pointing to untrusted sources -- Missing `go.sum` file in repository -- Modules with known vulnerabilities (`govulncheck`) -- Private module proxy misconfigurations - -#### 2.13 Installer & DLL Security - -**DLL Security:** -- DLL hijacking: application loads DLL from current directory before system paths -- DLL side-loading: legitimate app loading malicious DLL from same directory -- Missing Address Space Layout Randomization (ASLR) flag -- Missing Data Execution Prevention (DEP) / NX bit flag -- Unsigned DLLs in production deployments -- Export table exposing sensitive functions -- DLL injection vectors (missing process integrity levels) -- Insecure DLL search order (current directory before System32) - -**Installer Security (Inno Setup / NSIS / WiX / MSI):** -- Custom actions running with elevated privileges -- Missing digital signature on installer executable -- Insecure file permissions set during installation -- Hardcoded credentials in installer scripts -- Missing uninstall cleanup (leftover sensitive files/registry keys) -- Insecure temporary directory usage during installation -- Missing integrity checks on extracted files -- Pre-install validation missing (disk space, prerequisites) -- Insecure custom protocol handlers registered during install -- MSI custom actions with `Impersonate="no"` (running as SYSTEM) - -**Binary & Executable Security:** -- Missing Authenticode / code signing -- Missing checksum verification for downloaded updates -- Insecure auto-update mechanism (HTTP instead of HTTPS, no signature verification) -- Debug symbols included in release builds -- PDB files deployed to production -- Sensitive strings embedded in binary (use string search analysis) -- Missing compiler security flags (`/GS` buffer security check, `/DYNAMICBASE`, `/NXCOMPAT`) -- Insecure compiler optimizations that remove security checks - -#### 2.14 Logic & Business Flaws -- **Race Conditions**: Concurrent request exploitation -- **TOCTOU**: Time-of-check to time-of-use vulnerabilities -- **Business Logic Bypass**: Skipping payment, validation bypass -- **Mass Assignment**: Unfiltered model updates from user input -- **Insecure Deserialization**: Pickle, YAML, JSON parsing flaws - -### Phase 3: Database Security Analysis - -Deep analysis of database structures, configurations, and access patterns across SQL, NoSQL, and BaaS platforms. - -#### 3.1 SQL Database Security - -**Structure Analysis:** -- Schema design flaws enabling data leakage -- Missing foreign key constraints allowing orphaned/inconsistent data -- Overly permissive column types (VARCHAR(MAX) for sensitive fields) -- Missing audit columns (created_at, updated_at, created_by) -- Lack of soft delete patterns for compliance data - -**Query Security:** -- Dynamic SQL construction with string concatenation -- Stored procedures with SQL injection vectors -- Missing parameterized queries in ORM raw query usage -- Overly broad SELECT statements (SELECT * instead of column selection) -- Missing LIMIT/OFFSET on unbounded queries enabling data exfiltration -- Cursor-based attacks on large result sets - -**Access Control:** -- Database users with excessive privileges (DBA for app connections) -- Missing row-level security policies -- Default database credentials unchanged -- Database accessible from public networks -- Missing connection encryption (TLS/SSL) -- Connection string hardcoded or in version control - -**Platform-Specific SQL Checks:** -- **PostgreSQL**: RLS policies, pg_hba.conf, superuser roles, extension security (pg_crypto vs plaintext), search_path injection -- **MySQL/MariaDB**: GRANT privileges, LOAD DATA INFILE, secure-file-priv, binary log exposure -- **SQL Server**: xp_cmdshell enabled, TRUSTWORTHY database property, dynamic SQL in stored procedures -- **Firebird**: SYSDBA default password, UDF library security, role-based access -- **SQLite**: File permissions, encryption at rest (SEE/sqlcipher), journal mode security -- **Oracle**: TNS listener security, default accounts, privilege escalation via PL/SQL - -#### 3.2 NoSQL Database Security - -**MongoDB:** -- Authentication disabled (default in older versions) -- Bind address set to 0.0.0.0 (public access) -- Missing field-level encryption for PII -- NoSQL injection via operator injection ($gt, $ne, $regex) -- Aggregation pipeline injection -- Missing schema validation allowing arbitrary document structure -- GridFS exposed without access control -- Missing audit logging - -**Redis:** -- No authentication (requirepass not set) -- BIND set to 0.0.0.0 -- Dangerous commands enabled (FLUSHALL, CONFIG, DEBUG, EVAL) -- Lua script injection -- Missing rename-command for sensitive operations -- Unencrypted connections (no TLS) -- Keyspace exposure via INFO/KEYS commands - -**CouchDB:** -- Admin party mode (no authentication) -- Missing validate_doc_update functions -- Overly permissive _security objects -- CORS misconfiguration -- Futon admin panel exposed - -**DynamoDB:** -- Overly permissive IAM policies -- Missing encryption at rest -- No point-in-time recovery enabled -- Missing VPC endpoint for private access -- Scan operations without pagination limits - -**Cassandra:** -- Authenticator set to AllowAllAuthenticator -- Missing encryption (server-to-server, client-to-server) -- Overly broad permissions grants -- Missing audit logging - -#### 3.3 BaaS Platform Security - -**Supabase:** -- Missing RLS policies on tables with sensitive data -- RLS policies with `true` condition (allow all) -- Service role key exposed in client-side code -- Edge functions without authentication -- Storage buckets with public access for sensitive files -- Realtime subscriptions without authorization checks -- Missing database webhooks validation -- Exposed PostgREST configuration -- Missing rate limiting on API endpoints - -**Firebase/Firestore:** -- Database rules allowing unauthenticated read/write -- Firestore rules without proper `request.auth` checks -- Storage rules without file type/size validation -- Missing App Check enforcement -- API key exposed with overly permissive restrictions -- Cloud Functions without authentication -- Missing security rules for subcollections -- Realtime Database rules too permissive - -**Firebase Cost & Performance Security:** - -*Rule-Based Cost Detection:* -- Firestore rules with `allow read, write: if true;` (unlimited reads/writes = cost explosion) -- Firestore rules with `allow read: if request.auth != null;` (any authenticated user can read ALL documents) -- Realtime Database rules with `.read: true` or `.write: true` at root level -- Storage rules allowing unlimited file uploads without size/type restrictions -- Missing `request.resource.size` limits in Firestore create/update rules -- Rules that allow listing entire collections without filters (`allow list` without `request.query.limit`) - -*Query Cost Analysis:* -- `getDocs(collection(db, "collection"))` without pagination (reads entire collection) -- `getDocs(query(collection(db, "collection")))` without `.limit()` clause -- Missing cursor-based pagination (`startAfter`, `startAt`, `endBefore`, `endAt`) -- Realtime Database `ref.once('value')` on root or large nodes -- Excessive snapshot listeners (`onSnapshot`) without proper unsubscribe -- Multiple concurrent `getDoc()` calls instead of batched reads or `getAll()` -- `getDocs()` inside loops (N+1 query pattern in Firestore) -- Missing field selection (reading entire documents when only few fields needed) -- Collection group queries without security rules covering all subcollections - -*Cloud Functions Cost Triggers:* -- Firestore `onWrite`/`onCreate` triggers on high-write collections (each trigger = function invocation cost) -- Storage `onArchive`/`onDelete` triggers without event filtering -- HTTP functions without rate limiting (vulnerable to DDoS = cost spike) -- Scheduled functions running too frequently without purpose -- Functions with excessive memory allocation (always using 2GB when 256MB suffices) -- Missing `minInstances: 0` (keeping instances alive when not needed) -- `onRequest` functions without timeout configuration -- Functions that perform unnecessary reads before writes -- Recursive trigger patterns (function writes to same collection that triggers it) - -*Realtime Database Cost Patterns:* -- Deep listeners on root node (`ref.on('value')` at `/`) -- Missing `.indexOn` rules causing full database scans for queries -- Large JSON structures stored as single nodes instead of distributed paths -- Missing disconnect handlers leaving stale data -- Excessive `ref.set()` calls instead of batched `ref.update()` -- Not using `ref.once()` when real-time updates aren't needed - -*Storage Cost Patterns:* -- Missing file compression before upload (uploading uncompressed images/videos) -- No upload size limits enforced client-side AND server-side -- Missing file cleanup on account/document deletion -- Using `uploadBytes` instead of `uploadBytesResumable` for large files (memory spikes) -- Missing Firebase App Check for Storage (unauthorized uploads = cost) -- Not using CDN caching headers for public files (repeated downloads = cost) -- Missing lifecycle rules for old/deleted files - -*Firestore Index Cost:* -- Missing composite indexes causing query failures or full scans -- Over-indexing (indexes on fields rarely queried = unnecessary write cost) -- Single-field index exemptions not configured for high-write fields -- Array-contains queries on large arrays (index size bloat) - -*Connection & Instance Cost:* -- Excessive simultaneous Realtime Database connections (free tier: 100, paid: billed per connection) -- Firestore listeners not properly cleaned up on component unmount -- Missing offline persistence configuration causing reconnection storms -- Multiple Firebase app instances initialized unnecessarily -- Not using `firebase-admin` batch operations for bulk writes (individual writes = more cost) -- Missing connection pooling for server-side Firebase Admin SDK - -*Cost Estimation Patterns:* -- Estimate monthly read/write/delete costs based on code patterns -- Identify potential infinite loops in Firestore triggers -- Detect patterns where a single user action triggers N database operations -- Flag unbounded queries that could read millions of documents -- Calculate projected storage growth without cleanup policies -- Identify missing budget alerts and spending limits configuration - -**Appwrite:** -- Collection permissions set to `any` (public) -- Missing attribute-level validation -- Function execution without authentication -- Storage bucket permissions too broad -- Missing webhook signature validation -- API key scope too permissive - -**Neon (Serverless Postgres):** -- Connection string with credentials in code -- Missing SSL/TLS enforcement -- Branch-based access not restricted -- Pooler connection security -- Missing RLS policies (same as PostgreSQL) -- API key exposure - -**PocketBase:** -- Default admin credentials unchanged -- Collection rules too permissive -- Missing field encryption for sensitive data -- File upload rules without validation -- API rate limiting not configured - -**Convex:** -- Missing authentication in functions -- Overly broad document access rules -- Missing validation on mutations -- Sensitive data in function arguments (logged) -- Missing row-level security patterns - -### Phase 4: SLSA Build L3 (v1.2) Supply Chain Security - -Assess supply chain integrity against SLSA (Supply-chain Levels for Software Artifacts) framework. - -#### 4.1 Source Integrity -- **Version Control**: Signed commits verification, branch protection rules -- **Code Review**: Required reviews for merges, CODEOWNERS file present -- **Access Control**: Repository permissions audit, 2FA enforcement -- **Provenance**: Source location verifiable, build instructions documented - -#### 4.2 Build Integrity -- **Build Pipeline**: Automated CI/CD, reproducible builds, hermetic builds -- **Build Service**: Hosted build service (not developer machine), isolated environments -- **Build Provenance**: Signed build attestations, SLSA provenance generation -- **Artifact Signing**: Artifacts signed with Sigstore/cosign/GPG -- **Container Security**: Base image verification, no root user, minimal layers - -#### 4.3 Dependency Security -- **Lock Files**: package-lock.json, yarn.lock, Pipfile.lock, Cargo.lock present and committed -- **Pinning**: Dependencies pinned to exact versions (not ranges) -- **Verification**: Dependency integrity hashes verified -- **SBOM**: Software Bill of Materials generated and maintained -- **Vulnerability Scanning**: Automated dependency vulnerability scanning configured -- **Typosquatting**: Check for suspicious package names -- **License Audit**: All dependency licenses compatible with project license - -#### 4.4 Deployment Security -- **Environment Separation**: Clear separation between dev/staging/production -- **Secret Management**: Secrets in vault/manager, not in code or env files -- **Access Deployment**: Deployment access restricted and audited -- **Rollback Capability**: Ability to rollback deployments securely -- **Infrastructure as Code**: IaC templates audited for misconfigurations - -### Phase 5: OWASP ASVS Verification - -Systematic verification against OWASP Application Security Verification Standard (ASVS) 5.0.0 (stable since 2025-05-30). Reference requirements with the version, e.g. `v5.0.0-1.2.5`. - -#### V1: Architecture, Design and Threat Modeling -- Threat model documented and up-to-date -- Security architecture documented -- Trusted/untrusted boundary identification -- Security controls for each component - -#### V2: Authentication -- Password requirements (length, complexity, breach database check) -- Multi-factor authentication implementation -- Credential storage (bcrypt, scrypt, Argon2 - never MD5/SHA1) -- Session fixation prevention -- Account lockout mechanisms -- Credential recovery security - -#### V3: Session Management -- Session ID generation (cryptographically random) -- Session lifecycle (timeout, invalidation) -- Cookie security flags (HttpOnly, Secure, SameSite) -- Session binding to user attributes -- Concurrent session control - -#### V4: Access Control -- Default deny principle -- Function-level access control -- Data-level access control -- JWT access control verification -- OAuth scope validation - -#### V5: Validation, Sanitization and Encoding -- Input validation on all entry points -- Output encoding for context (HTML, JS, URL, SQL) -- Serialization security -- HTTP request smuggling prevention -- Mass assignment protection - -#### V6: Stored Cryptography -- Cryptographic key management -- Encryption algorithms (AES-256, RSA-2048+, never DES/RC4) -- Random number generation (CSPRNG) -- Key rotation procedures -- Certificate validation - -#### V7: Error Handling and Logging -- Error messages don't reveal sensitive info -- Security event logging (auth failures, access violations) -- Log integrity protection -- PII in logs (must be redacted) -- Log injection prevention - -#### V8: Data Protection -- Sensitive data identification and classification -- Data at rest encryption -- Data in transit encryption (TLS 1.2+) -- PII minimization -- Data retention and deletion policies - -#### V9: Communication Security -- TLS configuration (cipher suites, protocols) -- Certificate validation and pinning -- HTTP Strict Transport Security (HSTS) -- DNS security (DNSSEC, CAA records) - -#### V10: Malicious Code -- No backdoors or hidden functionality -- No time bombs or logic bombs -- Anti-tampering mechanisms -- Code obfuscation review (if applicable) - -#### V11: Business Logic -- Business logic flow validation -- Feature abuse prevention -- Automated threat protection (CAPTCHA, rate limiting) -- File upload validation and scanning - -#### V12: Files and Resources -- File upload restrictions (type, size, content) -- File execution prevention -- Path traversal protection -- File inclusion vulnerability prevention - -#### V13: API and Web Service -- API authentication and authorization -- API rate limiting and throttling -- GraphQL introspection disabled in production -- REST API input validation -- WebSocket security - -#### V14: Configuration -- Secure build and deployment configuration -- Unnecessary features/ports/services disabled -- Security headers properly configured -- Error handling configuration -- Production debug mode disabled - -### Phase 6: Regulatory Compliance Analysis - -#### 6.1 LGPD (Lei Geral de Proteção de Dados - Brazil) -- **Data Inventory**: Personal data mapping and classification -- **Legal Basis**: Processing legal basis documented (consent, legitimate interest, etc.) -- **Consent Management**: Granular consent collection, withdrawal mechanism -- **Data Subject Rights**: Access, correction, deletion, portability endpoints -- **DPO Contact**: Data Protection Officer contact information published -- **Cross-Border Transfer**: International data transfer safeguards -- **Breach Notification**: Incident response plan with 72h notification to ANPD -- **Privacy by Design**: Default privacy settings, data minimization -- **Third-Party Processing**: Data processing agreements with processors - -#### 6.2 GDPR (General Data Protection Regulation - EU) -- All LGPD checks apply, plus: -- **Data Protection Impact Assessment (DPIA)**: For high-risk processing -- **Records of Processing Activities (ROPA)**: Documented and maintained -- **Right to be Forgotten**: Automated data deletion capability -- **Data Portability**: Machine-readable export (JSON/CSV) -- **Consent Records**: Timestamped consent with version tracking -- **EU Representative**: Non-EU companies with EU representative appointed -- **Standard Contractual Clauses**: For international transfers - -#### 6.3 SOC 2 Type II -- **Security**: Access controls, logical/physical security -- **Availability**: SLA monitoring, incident management, disaster recovery -- **Processing Integrity**: Input validation, error handling, quality assurance -- **Confidentiality**: Data classification, encryption, access restrictions -- **Privacy**: Collection, use, retention, disclosure, disposal practices -- **Continuous Monitoring**: Automated compliance checks, audit logging -- **Change Management**: Documented change procedures, approval workflows - -#### 6.4 HIPAA (Health Insurance Portability and Accountability Act - US) -- **PHI Identification**: Protected Health Information mapped in codebase -- **Access Controls**: Role-based access to PHI, minimum necessary standard -- **Audit Logging**: All PHI access logged with user, timestamp, action -- **Encryption**: PHI encrypted at rest (AES-256) and in transit (TLS 1.2+) -- **Business Associate Agreements**: BAA with all third-party services handling PHI -- **Breach Notification**: HIPAA-specific breach notification procedures -- **De-identification**: Safe Harbor or Expert Determination methods -- **Integrity Controls**: PHI tampering detection and prevention - -#### 6.5 CCPA/CPRA (California Consumer Privacy Act / Privacy Rights Act) -- **Consumer Rights**: Right to know, delete, opt-out, correct, limit use -- **Sale/Sharing Disclosure**: "Do Not Sell" mechanism if applicable -- **Sensitive Personal Information**: SPI collection with opt-in consent -- **Service Provider Agreements**: CCPA-compliant contracts with processors -- **Data Minimization**: Collection limited to stated purposes -- **Retention Schedules**: Documented retention periods per data category - -### Phase 7: Vibe Coding Heuristics - -Specific heuristic analysis for vulnerability patterns commonly seen in AI-assisted code. CSReview does not prove AI authorship and does not perform deterministic authorship attribution. In the npm engine, `vibeRisk` is a static boolean heuristic attached to selected vulnerability patterns so the report can prioritize issues that commonly appear in rushed agent-generated code. - -#### 7.1 AI-Generated Code Patterns to Detect - -**Authentication & Authorization Bypass:** -- Placeholder authentication (if(true) { next(); }) -- Missing middleware on protected routes -- Client-side-only authentication checks -- Hardcoded bypass flags (DEBUG=true, SKIP_AUTH=true) -- JWT verification disabled or using 'none' algorithm -- Missing token expiration checks - -**Data Exposure Patterns:** -- SELECT * queries exposing all columns including sensitive fields -- API endpoints returning full user objects (including password hashes) -- Missing response filtering/sanitization -- Overly permissive CORS (Access-Control-Allow-Origin: *) -- Database connection strings in client-side code -- API keys in frontend environment variables - -**Injection Vulnerabilities (Common in AI Code):** -- String concatenation in SQL queries (AI often generates this pattern) -- Unsanitized user input in shell commands (exec, spawn, system) -- Template literals with user input (JS template injection) -- Raw HTML rendering (dangerouslySetInnerHTML, v-html, innerHTML) -- Eval-like functions with user data (eval, Function, deserialize) - -**Configuration Mistakes:** -- Default credentials unchanged (admin/admin, root/root) -- Development settings in production (debug=True, verbose logging) -- Missing security headers -- Permissive file upload (any type, any size) -- SSL/TLS verification disabled (NODE_TLS_REJECT_UNAUTHORIZED=0) -- Environment files committed to git - -**Dependency Issues:** -- Outdated or deprecated packages recommended by AI -- Non-existent packages (AI hallucination) -- Packages with known vulnerabilities -- Unnecessary dependencies increasing attack surface -- Mixed package managers (npm + yarn + pnpm) - -#### 7.2 AI-Assisted Development Anti-Patterns - -**Over-Confidence in Security:** -- "This is secure" comments without actual security measures -- Using crypto.createHash('md5') for passwords (AI often suggests this) -- Claiming code is "production-ready" without security review -- Missing error handling with generic catch-all -- Suggesting security-through-obscurity as primary defense - -**Missing Security Thinking:** -- No input validation on user-facing endpoints -- No rate limiting on authentication endpoints -- No logging of security events -- Missing CSRF protection -- No file upload validation -- Missing pagination on list endpoints (DoS vector) - -**Copy-Paste Vulnerabilities:** -- Stack Overflow code with known vulnerabilities -- Tutorial code with intentional security gaps -- Outdated security patterns (MD5, DES, RC4) -- Hardcoded example credentials from documentation - -#### 7.3 Vibe Coding Heuristic Labels - -Each finding may include a "Vibe Risk" flag indicating that the vulnerability matches a pattern often introduced during AI-assisted development. This is a static boolean heuristic in the engine and a prioritization hint for the agent; it does not prove AI authorship. - -| Label | Meaning | Limit | -|-------|---------|-------| -| **Vibe Risk: Yes** | Pattern commonly appears in rushed or AI-assisted code | Not authorship evidence | -| **Vibe Risk: No** | Pattern is not tagged as a vibe-coding heuristic | Not proof the code is human-written | - -### Phase 8: Report Generation - -Generate TWO reports under the selected output directory, normally `/csreview-reports/`. Report files are allowed audit artifacts; they do not mean the CSReview skill was installed inside the project: - ---- - -## Report 1: HTML Report (For Humans) - -File: `csreview-reports/_security-report.html` - -### Executive Summary Section -- **Overall Security Score**: 0-100 scale with color coding -- **Severity Distribution**: Pie/bar chart (Critical/High/Medium/Low/Info) -- **Vulnerability Categories**: Bar chart by category -- **Top 5 Critical Findings**: Quick reference cards -- **Risk Assessment**: Overall risk level (Critical/High/Medium/Low) -- **Scan Metadata**: Timestamp, files analyzed, lines scanned - -### Technical Findings Section -For each vulnerability found: - -``` -┌─────────────────────────────────────────────────┐ -│ [SEVERITY BADGE] Vulnerability Title │ -├─────────────────────────────────────────────────┤ -│ Category: Injection / Auth / Data Leakage / etc │ -│ Location: src/file.ts:142 │ -│ CWE: CWE-89 (SQL Injection) │ -│ │ -│ Description: │ -│ Detailed explanation of the vulnerability │ -│ │ -│ Vulnerable Code: │ -│ [syntax-highlighted code snippet] │ -│ │ -│ Potential Exploitation Path (theoretical, unverified): │ -│ Static-analysis hypothesis; not a validated or executed exploit. │ -│ │ -│ Impact: │ -│ What could happen if exploited │ -│ │ -│ Recommended Fix: │ -│ [syntax-highlighted corrected code] │ -│ │ -│ References: │ -│ OWASP, CVE links, documentation │ -└─────────────────────────────────────────────────┘ -``` - -### Report Features -- **Navigation**: Sidebar with anchor links to each finding -- **Filtering**: Filter by severity, category, or status -- **Syntax Highlighting**: Code blocks with language-specific colors -- **Color Coding**: Red=Critical, Orange=High, Yellow=Medium, Blue=Low, Gray=Info -- **Export**: Button to download findings as JSON -- **Print-Friendly**: Optimized CSS for PDF export -- **Responsive**: Works on desktop and mobile - -### HTML Template Structure - -```html - - - - - - Security Audit Report - [Project Name] - - - -
-

Security Audit Report

-
Project: [name] | Date: [timestamp] | Score: [score]/100
-
- - - -
-
- - - - - - - - -
- -
- -
-
- CRITICAL -

SQL Injection in User Authentication

-
-
- Category: Injection - Location: src/auth.ts:45 - CWE: CWE-89 - Vibe Risk: Yes - Compliance: OWASP ASVS V5.3, GDPR Art.32 -
-
-

Description

-

...

-

Vulnerable Code

-
...
-

Potential Exploitation Path (theoretical, unverified)

-

Static-analysis hypothesis only; not a validated or executed exploit.

-

Impact

-

...

-

Recommended Fix

-
...
-

References

-
    ...
-
-
-
- -
- - - - - -
- -
- - - - - -
- -
- - - - - -
- -
- - - -
- -
- - - - - -
-
- -
- -

Generated by CSReview - Code Security Review Skill

-
- - - - +csreview . --local-dast-url http://localhost:3000 --confirm-local-dast --agent-name codex ``` ---- - -## Report 2: Markdown Report (For AI Agents) - -File: `csreview-reports/_security-findings.md` - -This report is structured for humans and AI coding agents to parse, understand, prioritize, and plan remediations. It contains machine-readable findings with exact file locations, vulnerable code evidence, exploitation context, and recommended remediation approaches. It is **not** permission for CSReview to change the audited code. **Always generated in English** regardless of user language. - -### Markdown Structure - -```markdown -# Security Findings Report +Status labels — honest semantics: the built-in probe produces `DAST-SUSPECTED` (anomalous local response requiring human review) and `DAST-CLEAN` (check passed). `DAST-CONFIRMED` is a reserved label for dynamically reproduced evidence from a dedicated local DAST tool the agent ran separately (e.g. OWASP ZAP or Nikto, only when installed, after the same pre-flight and confirmation, against the same confirmed local target) — the built-in probe never emits it. Never probe external hosts, never use destructive payloads or DELETE, and do not send mutating requests without an explicit local allowlist and confirmed data-mutation risk. Full protocol: `reference/local-dast.md`. -**Project**: [project-name] -**Date**: [YYYY-MM-DD HH:MM:SS] -**Security Score**: [score]/100 -**SLSA Level**: [0-3] -**OWASP ASVS Coverage**: [percentage]% -**Total Findings**: [count] -**Critical**: [count] | **High**: [count] | **Medium**: [count] | **Low**: [count] | **Info**: [count] -**Vibe Coding Heuristics**: [Vibe Risk: count] | [Not flagged: count] - ---- - -## Summary Table - -| ID | Severity | Category | File | Line | Issue | Vibe Risk | Compliance | -|----|----------|----------|------|------|-------|-----------|------------| -| 001 | CRITICAL | SQL Injection | src/auth.ts | 45 | Raw SQL query with user input | Vibe Risk: Yes | ASVS V5.3, GDPR Art.32 | -| 002 | HIGH | XSS | src/components/UserInput.vue | 12 | Unsanitized v-html binding | Vibe Risk: Yes | ASVS V5.2, LGPD Art.46 | -| ... | ... | ... | ... | ... | ... | ... | ... | - ---- +## Built-in Code Review Modes -## Findings +CSReview includes integrated review modes (no extra skills required) — methodology in `reference/review-modes.md`: -### Finding #001 - -**Severity**: CRITICAL -**Category**: SQL Injection -**CWE**: CWE-89 -**File**: `src/auth.ts` -**Line**: 45 -**Status**: PENDING -**Vibe Risk**: Yes -**Compliance**: OWASP ASVS V5.3, GDPR Art.32, LGPD Art.46, SOC 2 CC6.1 - -#### Description -Raw SQL query constructed with string concatenation using user-supplied input, allowing SQL injection attacks. - -#### Vulnerable Code -```typescript:src/auth.ts:40-50 -// Lines 40-50 -const query = `SELECT * FROM users WHERE email = '${email}' AND password = '${password}'`; -const result = await db.query(query); ``` - -#### Potential Exploitation Path (theoretical, unverified) -This is a hypothesis derived from static analysis, not a validated or executed exploit. - -1. Attacker submits email: `' OR '1'='1` -2. Query becomes: `SELECT * FROM users WHERE email = '' OR '1'='1' AND password = 'anything'` -3. Authentication bypass achieved - -#### Impact -- Full authentication bypass -- Access to any user account -- Potential data exfiltration via UNION-based injection -- LGPD violation: unauthorized access to personal data (Art.46) -- GDPR violation: inadequate security measures (Art.32) - -#### Fix Required -Replace raw SQL query with parameterized query: - -```typescript:src/auth.ts:40-50 -// FIXED: Use parameterized query -const query = 'SELECT * FROM users WHERE email = $1 AND password = $2'; -const result = await db.query(query, [email, password]); +@csreview -> Full security audit (engine + agent passes) +@csreview review [files] -> Standard code review +@csreview adversarial [files] -> Adversarial (red-team) review +@csreview security-review [files] -> Security-focused review of changes +@csreview request-review [PR/branch/commit] -> Review of a change set +@csreview review csreview-reports/codex_security-findings.md -> Plan remediation from a report (CSReview never edits source) ``` -#### References -- OWASP: https://owasp.org/www-community/attacks/SQL_Injection -- CWE-89: https://cwe.mitre.org/data/definitions/89.html -- OWASP ASVS V5.3.3: https://owasp.org/www-project-application-security-verification-standard/ - ---- - -## Database Security Findings - -### SQL Database Issues -| ID | Severity | Database | File | Issue | Recommendation | -|----|----------|----------|------|-------|----------------| -| DB001 | CRITICAL | PostgreSQL | src/db.ts:23 | Missing RLS on users table | Enable RLS with user-scoped policies | - -### NoSQL Database Issues -| ID | Severity | Database | File | Issue | Recommendation | -|----|----------|----------|------|-------|----------------| -| DB010 | HIGH | MongoDB | src/models/user.js:15 | NoSQL injection via $gt operator | Use MongoDB driver query builders | - -### BaaS Platform Issues -| ID | Severity | Platform | Config | Issue | Recommendation | -|----|----------|----------|--------|-------|----------------| -| BAAS001 | CRITICAL | Supabase | supabase/config.ts:5 | Service role key in client code | Move to server-side environment | - -### Firebase Cost & Performance Issues -| ID | Severity | Category | File | Issue | Cost Impact | Recommendation | -|----|----------|----------|------|-------|-------------|----------------| -| COST001 | CRITICAL | Firestore Rules | firestore.rules:12 | `allow read, write: if true;` | Unlimited reads/writes = cost explosion | Restrict to authenticated users with resource-level checks | -| COST002 | HIGH | Query | src/hooks/useUsers.ts:23 | `getDocs(collection(db, "users"))` without pagination | Reads entire collection | Add `.limit()` and cursor-based pagination | -| COST003 | HIGH | Cloud Functions | functions/src/index.ts:45 | `onWrite` trigger on high-write collection | Each write = function invocation cost | Filter events or use batch processing | -| COST004 | MEDIUM | Storage | src/utils/upload.ts:15 | No file size limit before upload | Large files = storage + bandwidth cost | Add client-side + server-side size validation | -| COST005 | MEDIUM | Realtime DB | src/App.tsx:30 | `ref.on('value')` on root node | Downloads entire database on every change | Listen to specific paths only | -| COST006 | LOW | Connections | src/context/Auth.tsx:10 | Multiple `onSnapshot` listeners without cleanup | Billed per connection | Unsubscribe on component unmount | - -### .NET / Delphi / Go / Binary Security Issues -| ID | Severity | Category | File | Issue | Recommendation | -|----|----------|----------|------|-------|----------------| -| DOTNET001 | HIGH | ASP.NET | Controllers/AdminController.cs:15 | Missing `[Authorize]` attribute | Add authorization attribute | -| DELPHI001 | CRITICAL | Database | Unit1.pas:45 | Hardcoded Firebird credentials | Use encrypted connection string storage | -| GO001 | HIGH | Web | main.go:67 | SQL injection via `fmt.Sprintf` | Use parameterized queries with `db.Query` | -| DLL001 | MEDIUM | Binary | installer/setup.iss:23 | Missing digital signature | Sign installer with Authenticode certificate | - ---- - -## SLSA Assessment - -| Requirement | Status | Details | -|-------------|--------|---------| -| Source Version Control | [PASS/FAIL] | Git with signed commits | -| Branch Protection | [PASS/FAIL] | Required reviews configured | -| Build Provenance | [PASS/FAIL] | SLSA attestations generated | -| Dependency Pinning | [PASS/FAIL] | Lock files present | -| Artifact Signing | [PASS/FAIL] | Sigstore/cosign configured | - -**Current SLSA Level**: [0-3] -**Recommendations**: [list of actions to reach SLSA Build L3 (v1.2)] - ---- - -## OWASP ASVS Compliance - -| Category | Name | Pass | Fail | N/A | Score | -|----------|------|------|------|-----|-------| -| V1 | Architecture | 5 | 2 | 3 | 71% | -| V2 | Authentication | 8 | 4 | 0 | 67% | -| ... | ... | ... | ... | ... | ... | - -**Overall ASVS Score**: [percentage]% - ---- - -## Compliance Matrix - -### LGPD -| Article | Requirement | Status | Finding Reference | -|---------|-------------|--------|-------------------| -| Art.46 | Security measures | FAIL | #001, #003 | -| Art.48 | Breach notification | PASS | - | - -### GDPR -| Article | Requirement | Status | Finding Reference | -|---------|-------------|--------|-------------------| -| Art.32 | Security of processing | FAIL | #001 | -| Art.25 | Data protection by design | PASS | - | - -### SOC 2 Type II -| Criteria | Requirement | Status | Finding Reference | -|----------|-------------|--------|-------------------| -| CC6.1 | Logical access controls | FAIL | #001, #005 | -| CC6.7 | Data transmission | PASS | - | - -### HIPAA -| Safeguard | Requirement | Status | Finding Reference | -|-----------|-------------|--------|-------------------| -| 164.312(a) | Access control | FAIL | #002 | -| 164.312(e) | Transmission security | PASS | - | - -### CCPA/CPRA -| Section | Requirement | Status | Finding Reference | -|---------|-------------|--------|-------------------| -| 1798.100 | Right to know | FAIL | Missing endpoint | -| 1798.105 | Right to delete | PASS | - | - ---- - -## Vibe Coding Assessment - -### Vibe-Risk Findings -Findings matching vulnerability patterns that commonly appear in rushed or AI-assisted code. This does not prove AI authorship. - -| ID | Pattern | Heuristic | Recommendation | -|----|---------|-----------|----------------| -| 001 | String concatenation SQL | Vibe Risk: Yes | Replace with parameterized queries | -| 003 | MD5 password hashing | Vibe Risk: Yes | Switch to bcrypt/Argon2 | - -### AI-Assisted Code Quality Notes -- **Security Awareness**: [Low/Medium/High] -- **Common AI Anti-Patterns Found**: [count] -- **Recommendation**: [brief guidance for the user] - ---- - -## Fix Priority Order - -Apply fixes in this order: - -1. **CRITICAL findings first**: Authentication bypass, SQL injection, RCE, exposed secrets -2. **HIGH findings second**: XSS, CSRF, IDOR, missing authorization -3. **MEDIUM findings third**: CORS misconfiguration, insecure headers, rate limiting -4. **LOW findings fourth**: Defense-in-depth improvements, best practices -5. **INFO findings last**: Recommendations, documentation updates +## When to Invoke -Within each severity, prioritize by: -1. Vibe-risk findings (patterns often repeated in rushed or AI-assisted code) -2. Compliance-critical findings (regulatory violations) -3. Database security issues -4. Supply chain concerns +- User requests a security review, code audit, vulnerability scan, or pentest-style static analysis +- User asks about exposed secrets, data leakage, SQL injection, XSS, or auth flaws +- Pre-release/deployment review of the local workspace; Supabase/Firebase/Appwrite/BaaS rule review +- Compliance correlation requests (LGPD, GDPR, SOC 2, HIPAA); vibe-coding verification of AI-written code +- Any `@csreview ...` invocation listed above -## Agent Instructions +## Supported Technologies -When fixing these findings (note: CSReview only reports; the coding agent or developer applies fixes): +Frontend (React, Vue, Nuxt, Angular, Svelte, Next.js), mobile (Flutter, Kotlin/Android, Swift/iOS, React Native), backend (Node.js, Python, C#/.NET, Go, Java, PHP, Ruby), systems (C, C++, Rust), desktop (Electron, Tauri), Delphi/Lazarus/Free Pascal, SQL/NoSQL databases, BaaS platforms (Supabase, Firebase, Appwrite, Neon, PocketBase, Convex, and similar), installers/DLLs/binaries, and OS-specific surfaces (macOS, iOS, Linux, Windows). Detection depth varies by stack: language-specific engine rules exist for JavaScript/TypeScript, Python, C#, Go, C/C++, and Delphi; other stacks rely on Semgrep, OSV-Scanner, and the agent checklists in `reference/security-checklists.md`. -1. Read the vulnerable file at the specified line numbers -2. Understand the context before applying the fix -3. If the framework is unfamiliar, research official documentation before applying fixes -4. Treat the recommendation as guidance, not a patch; inspect the framework, schema, tests, and surrounding code before changing anything -5. Verify the fix doesn't break existing functionality -6. Mark the finding as FIXED after successful application -7. Run tests to ensure no regressions -8. Commit changes with descriptive message: `fix(security): [brief description of fix]` -9. After all fixes, re-run CSReview to verify remediation -``` +### AI Agent Compatibility ---- +| Agent | Integration | +|-------|-------------| +| Claude Code | Global skill via `~/.claude/skills/csreview/SKILL.md` | +| Codex | Global skill via `~/.codex/skills/csreview/SKILL.md` or `~/.agents/skills/csreview/SKILL.md` | +| Trae / SOLO | Global skill via `~/.trae/skills/csreview/SKILL.md` | +| OpenCode / Qwen CLI / Antigravity / Qoder / Cursor / Windsurf / Cline / Copilot CLI / Aider | Compatible via each agent's global rules/instructions mechanism when supported | -## Severity Classification - -| Severity | Criteria | Response Time | -|----------|----------|---------------| -| **Critical** | Direct data breach, RCE, auth bypass, exposed PII | Immediate fix required | -| **High** | Significant vulnerability, exploitable with effort | Fix within 24-48h | -| **Medium** | Moderate risk, requires specific conditions | Fix within 1 week | -| **Low** | Minor issue, defense-in-depth improvement | Fix in next sprint | -| **Info** | Best practice recommendation, no direct risk | Consider for improvement | - -## Built-in Code Review System - -CSReview includes a complete code review system that eliminates the need for external review skills. This system provides 5 integrated review modes: - -### Review Mode 1: Standard Code Review (`codex:review` equivalent) - -Comprehensive code review covering: - -**Code Quality:** -- Code readability and maintainability -- Naming conventions consistency -- Function/method complexity (cyclomatic complexity) -- Dead code detection -- Code duplication identification -- SOLID principles adherence -- DRY principle violations -- Separation of concerns - -**Architecture:** -- Design pattern appropriateness -- Module coupling analysis -- Dependency direction violations -- Interface segregation -- Single responsibility violations - -**Performance:** -- Algorithm complexity (O(n) analysis) -- Memory leak potential -- Unnecessary object creation -- Database query optimization (N+1 queries) -- Caching opportunities -- Bundle size impact - -**Testing:** -- Test coverage gaps -- Missing edge case tests -- Test isolation issues -- Mock overuse detection -- Missing integration tests - -**Documentation:** -- Missing JSDoc/docstrings on public APIs -- Outdated comments -- Missing README sections -- Undocumented breaking changes - -### Review Mode 2: Adversarial Review (`codex:adversarial-review` equivalent) - -Red-team mindset review that actively tries to break the code: - -**Attack Vectors:** -- Boundary condition exploitation -- Race condition identification -- Resource exhaustion scenarios -- Error handling bypass attempts -- State corruption possibilities -- Input validation gaps at every boundary - -**Failure Modes:** -- What happens when external services are down? -- What happens with malformed input at each layer? -- What happens under extreme load? -- What happens with concurrent modifications? -- What happens when disk/memory is full? - -**Edge Cases:** -- Empty/null/undefined inputs -- Maximum size inputs -- Unicode/special characters -- Timezone-sensitive operations -- Floating point precision issues -- Integer overflow scenarios - -**Adversarial Questions:** -- "How can I make this code fail?" -- "What's the worst input an attacker could provide?" -- "What assumptions does this code make that could be wrong?" -- "What happens if I remove this check?" -- "Can I bypass this validation?" - -### Review Mode 3: Security-Focused Code Review (`code-review` equivalent) - -Security-specific review integrated with the main CSReview analysis: - -- All Phase 2 (Ultra-Deep Security) checks applied to specific code changes -- All Phase 3 (Database Security) checks for data layer changes -- All Phase 7 (Vibe Coding) pattern detection for AI-generated code -- Security impact assessment of each change -- Threat model updates required for architectural changes - -### Review Mode 4: Requesting Code Review (`requesting-code-review` equivalent) - -When a developer or coding agent requests a review: - -**Review Request Protocol:** -1. Identify the scope of changes (files, functions, modules) -2. Determine review depth (quick scan, standard, deep) -3. Select applicable review modes (quality, adversarial, security) -4. Generate review checklist based on change type -5. Execute review and generate findings -6. Prioritize findings by severity and actionability - -**Change-Type Detection:** -- **New feature**: Full review with adversarial testing -- **Bug fix**: Verify fix correctness, check for regression -- **Refactoring**: Verify behavior preservation, check for missed cases -- **Configuration change**: Security impact assessment -- **Dependency update**: Vulnerability and license check -- **Database migration**: Data integrity and rollback assessment - -### Review Mode 5: Receiving Code Review (`receiving-code-review` equivalent) - -When CSReview findings are received by a coding agent: - -**Response Protocol:** -1. Parse findings from the MD report -2. Categorize by severity and type -3. For each finding: - - Acknowledge the issue - - Research the fix (if framework is unfamiliar, consult official docs) - - Propose a solution - - Apply the fix (coding agent responsibility) - - Verify the fix doesn't introduce new issues -4. Report back with summary of changes made - -**Fix Verification Checklist:** -- [ ] Fix addresses the specific vulnerability -- [ ] Fix doesn't break existing functionality -- [ ] Fix follows framework best practices -- [ ] Fix doesn't introduce new vulnerabilities -- [ ] Fix includes appropriate tests (if applicable) -- [ ] Fix is documented (if behavior changes) - -### Integrated Review Workflow - -When CSReview is invoked, it can operate in any of these modes: +Regardless of agent: the HTML report is generated for the user (human review); the MD report is always English for agent consumption; behavior and report formats stay consistent. -``` -@csreview → Full 8-phase security audit -@csreview review [files] → Standard code review (Mode 1) -@csreview adversarial [files] → Adversarial review (Mode 2) -@csreview security-review [files] → Security code review (Mode 3) -@csreview request-review [PR/branch/commit] → Request review of changes (Mode 4) -@csreview review csreview-reports/codex_security-findings.md → Plan remediation from report without CSReview editing source code -``` +## Output -## Execution Workflow +- **Primary**: `csreview-reports/_security-report.html` — visual report for human review +- **Secondary**: `csreview-reports/_security-findings.md` — structured English report for remediation planning +- **CI**: `csreview-reports/_security.sarif` — SARIF 2.1.0 (pair with `--fail-on`) +- **Verbal**: summary of CRITICAL/HIGH findings, mode, and disclosed gaps; JSON export available from the HTML report -When invoked, follow these steps: - -1. **Confirm global skill scope**: If the task involves installing or updating CSReview itself, use the agent's global skills directory by default. Do not install CSReview into the analyzed project unless the user explicitly requested project-local installation. -2. **Announce the scan**: Inform user about starting security analysis -3. **Phase 0 - Tool Detection**: Attempt Semgrep first (`semgrep --version`, then `semgrep --config auto --json --quiet `). Then attempt read-only dependency scanners (`pnpm audit --json` when `pnpm-lock.yaml` exists, otherwise `npm audit --json` for npm lockfiles, plus `osv-scanner scan --format json ` when installed). Detect installed framework/security tools (bandit, trivy, snyk, gosec, eslint, codeql, pip-audit, etc.). Report which tools are available and which are missing. Run all available relevant tools against the project. Normalize tool output into unified findings format. -4. **Phase 1 - Recon**: Scan project structure, identify technologies, map attack surface -5. **Phase 2 - Deep Analysis**: Systematically check each vulnerability category (injection, auth, data leakage, XSS, CSRF, config, deps, cloud, .NET, Delphi/Lazarus, Go, DLL/installer, platform-specific, logic flaws) -6. **Phase 3 - Database Security**: Analyze SQL/NoSQL/BaaS database structures, access patterns, Firebase cost/performance, and configurations -7. **Phase 4 - SLSA Build L3 (v1.2)**: Assess supply chain integrity (source, build, dependency, deployment) -8. **Phase 5 - OWASP ASVS**: Systematic verification against V1-V14 categories -9. **Phase 6 - Compliance**: Check LGPD, GDPR, SOC 2, HIPAA, CCPA-CPRA requirements -10. **Phase 7 - Vibe Coding**: Flag static heuristics for vulnerability patterns commonly seen in rushed or AI-assisted code -11. **Progress updates**: Keep user informed of analysis progress throughout -12. **Phase 8 - Report Generation**: Create BOTH reports: - - `csreview-reports/_security-report.html` (visual report in user's language for human review) - - `csreview-reports/_security-findings.md` (structured report in English for human/coding-agent remediation planning) -13. **Deliver reports**: Provide absolute paths to both generated files: - - HTML report path for the user to click/open in a browser - - Markdown report path for the coding agent to analyze before remediation -14. **Summary**: Give brief verbal summary of critical/high findings including tool-detected vs AI-estimated findings, compliance gaps, vibe coding risks, and Firebase cost issues -15. **Offer next step**: Ask whether the user wants a prioritized remediation plan or wants a separate coding agent session to apply selected fixes with project-context validation. - -## Important Guidelines - -- **READ-ONLY**: CSReview NEVER modifies, deletes, moves, or creates source code in the analyzed project. It only identifies, reports, and suggests remediation approaches. -- **Global Installation Default**: CSReview MUST be installed in the agent's global skill/instruction environment by default. Do not place CSReview skill files in the analyzed project unless the user explicitly requested project-local installation. -- **Tool Detection First**: ALWAYS run Phase 0 (tool detection) before any analysis. The user must know which mode is active. -- **Agent-Only Risk Disclosure**: When operating in Agent-Only mode, the agent MUST explicitly warn the user that findings have lower confidence and that real security tools should be installed for production audits. A less knowledgeable agent may miss critical vulnerabilities or produce incorrect recommendations. -- **Semgrep Required Baseline**: Always attempt to run `semgrep` (universal) and the language-specific primary tool for the project being analyzed. If Semgrep is missing, mark the run lower-confidence and provide installation commands. -- **Dependency SCA Complement**: Run `pnpm audit --json` for Node.js roots with `pnpm-lock.yaml`, otherwise run `npm audit --json` for npm lockfiles. Also run `osv-scanner scan --format json ` when OSV-Scanner is installed. Never run dependency fix/update commands during CSReview. -- **External Research Required When Uncertain**: If the agent is unsure about framework behavior, safe configuration, version-specific APIs, exploitability, or remediation, it MUST search external sources before making a confident claim. Use official framework documentation first, then vendor security advisories and specialized security sources such as OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, and Snyk. Do not guess. -- **All Relevant Files Are Scanned**: All relevant in-scope files are scanned; generated, vendor, minified, and IDE directories (e.g. `dist`, `build`, `vendor`, `bin`, `obj`, `.next`, `node_modules`, `.git`) and the generated reports are excluded. Do not rely on sampling for in-scope source. -- **Never expose secrets in chat**: If you find hardcoded credentials, mention them in the reports only, not in the conversation -- **Be thorough but practical**: Focus on exploitable vulnerabilities, not theoretical edge cases -- **Provide actionable remediation**: Every finding must include concrete remediation guidance, but the fix is applied by the human developer or coding agent after reviewing context, not by CSReview. -- **Context matters**: Consider the application type (internal tool vs public API) when assessing severity -- **False positives**: Only report confirmed vulnerabilities, avoid noise -- **Prioritize**: Critical and High findings should be clearly highlighted -- **Respect scope**: Only analyze code in the specified project, don't test external services -- **MD report precision**: File paths and line numbers in the MD report must be exact so humans or coding agents can safely inspect and plan remediation. -- **HTML report language**: Generate the HTML report in the same language as the user's conversation language -- **MD report language**: Always generate the MD report in English regardless of user language (for agent consumption) -- **Compliance findings**: Clearly map each compliance gap to the specific regulation article/section -- **Vibe coding markers**: Tag findings with a Vibe Risk boolean (Yes/No). This is a heuristic signal, not a numeric score and not proof of AI authorship. -- **Database findings**: Include specific database engine version requirements when relevant -- **SLSA scoring**: Clearly indicate current SLSA level and what's needed to reach level 3 -- **Unknown frameworks**: If the analyzed code uses a framework the agent is not familiar with (e.g., Lazarus, Delphi, niche frameworks), the agent MUST research using official documentation from the framework's official website, database vendor documentation, and community forums before reporting findings and suggesting fixes -- **Documentation sourcing**: For each finding, reference the official documentation of the relevant framework, database, or platform (e.g., PostgreSQL docs, Supabase docs, Firebase docs, Appwrite docs, MongoDB docs, etc.) -- **Forum research**: When encountering unusual errors or obscure vulnerabilities, search relevant community forums (Stack Overflow, GitHub Issues, framework-specific forums) to provide accurate, tested solutions -- **Transparency**: Report all steps taken during the analysis, including what was checked, what was found, and what research was conducted to arrive at recommendations - -## Example Invocation - -User: "Run a security review on this project" -User: "Check for vulnerabilities in my Supabase backend" -User: "Audit this code for data leakage" -User: "Do a pentest analysis before deployment" -User: "Find any SQL injection or XSS vulnerabilities" -User: "Verify LGPD and GDPR compliance in my codebase" -User: "Check if my code has vibe coding vulnerabilities" -User: "Analyze my database security for PostgreSQL and MongoDB" -User: "Run OWASP ASVS verification on this project" -User: "Check supply chain security (SLSA)" -User: "@csreview" -User: "@csreview review src/auth.ts src/middleware/" -User: "@csreview adversarial src/api/payments/" -User: "@csreview security-review src/components/" -User: "@csreview request-review main..feature/auth" -User: "@csreview review csreview-reports/codex_security-findings.md" +## Reference Index -## Output +Load these on demand; they are reference material, not standing instructions: -- **Primary**: `csreview-reports/_security-report.html` under the selected output directory (visual report in user's language for human review) -- **Secondary**: `csreview-reports/_security-findings.md` under the selected output directory (structured report in English for remediation planning) -- **Tertiary**: Verbal summary of critical/high findings in chat including compliance gaps and vibe coding risks -- **Optional**: JSON export available via HTML report button +- `reference/security-checklists.md` — contextual review checklists (injection, auth, BaaS, platform-specific, database, Firebase cost) +- `reference/compliance-frameworks.md` — SLSA / ASVS / LGPD / GDPR / SOC 2 / HIPAA / CCPA correlation (and what the engine does NOT compute) +- `reference/tooling.md` — tool detection, read-only invocation forms, installation pointers +- `reference/subagents.md` — scatter-gather protocol detail and partial-file contract +- `reference/local-dast.md` — Phase 9 protocol detail and guard semantics +- `reference/review-modes.md` — the five review-mode methodologies +- `reference/reports.md` — actual report anatomy and the canonical finding schema ````
-## Purpose & Utility - -**CSReview** is a universal AI agent skill for development-time security alignment of the local workspace a developer is actively building. It applies a penetration tester's adversarial mindset to local source, configuration, dependencies, and infrastructure files (static SAST + SCA), but it does not perform live penetration testing against running, deployed, or production systems. - -### CSReview is READ-ONLY - -CSReview **NEVER modifies, deletes, or moves any files** in the analyzed project. It only: -- Identifies security problems and locates them precisely -- Suggests solutions based on the frameworks and technologies in use -- Researches official documentation when encountering unfamiliar frameworks -- Reports all findings to the developer and coding agent - -The actual fixes are applied by the human developer or the coding agent, not by CSReview. - -CSReview exists to slow down unsafe "vibe coding" before release: it inspects local code, dependency manifests, framework configuration, database/BaaS rules, frontend/backend boundaries, and platform-specific surfaces, then writes a detailed report explaining what is exposed and why. It does not assume enough business or schema context to change the audited system itself. - -### Scope - -- **IN SCOPE**: the local development workspace/project, including local source code, configuration, `.env` files, infrastructure-as-code, and BaaS rule files. Local SAST/SCA tools such as Semgrep, npm/pnpm package audit, OSV-Scanner, and framework-native scanners may be run against that local code only. Optional Phase 9 Local DAST is allowed only after remediation work, only with explicit user confirmation, and only against `localhost`, `127.0.0.1`, or the IPv6 loopback `[::1]`. -- **GOAL**: improve the SECURITY and EFFICIENCY (cost/performance) of the project under development. -- **OUT OF SCOPE / PROHIBITED**: testing, probing, or calling live, deployed, staging, or production systems; external service endpoints used by the app; unconfirmed dynamic testing; DAST against non-local running targets; modifying audited code; exfiltrating data. -- **Reference documentation research is ALLOWED**: reading OWASP, CWE, CVE/NVD, OSV, vendor advisories, and official framework documentation to ground remediation is allowed. That is reading documentation, not probing a target. - -### Ethical Use & Attribution - -CSReview may be copied, forked, adapted, and replicated under the MIT License. The project asks that every copy and derivative use it for good: authorized security reviews, local development hardening, education, and remediation work in the spirit of an ethical hacker / White Hat Hacker. - -Do not use CSReview to support unauthorized intrusion, exploitation, credential theft, data exfiltration, surveillance, or harm. -Credit should be preserved where practical: CSReview is a **Deck Software** project idealized by **Márcio PS**, built with assistance, review, and ideas from AI coding agents and tools including Claude Code, Trae, MiniMax, Qwen, Cascade da Windsurf, Codex, GLM 5.1, MiMo V2.5 Pro, and other reviewer agents. +## Reference documentation -### Global Skill Installation Only +The agent loads these on demand (they ship with the package and stay out of the agent's standing context): -CSReview is a **global agent skill**. Install it in the AI agent's global skills directory, never inside the project being audited unless the user explicitly asks for a project-local installation. +| File | Contents | +|------|----------| +| [reference/security-checklists.md](csreview/reference/security-checklists.md) | Contextual review checklists: injection, auth, data leakage, BaaS rules, platform-specific surfaces (.NET, Delphi/Lazarus, Go, installers/DLLs, macOS/iOS/Linux/Windows), database security, Firebase cost patterns | +| [reference/compliance-frameworks.md](csreview/reference/compliance-frameworks.md) | SLSA Build L3 (v1.2), OWASP ASVS 5.0.0, LGPD/GDPR/SOC 2/HIPAA/CCPA-CPRA correlation — and what the engine deliberately does NOT compute | +| [reference/tooling.md](csreview/reference/tooling.md) | Tool detection, read-only invocation forms, installation pointers | +| [reference/subagents.md](csreview/reference/subagents.md) | Scatter-gather subagent protocol and the partial-file contract the engine enforces | +| [reference/local-dast.md](csreview/reference/local-dast.md) | Phase 9 local-probe protocol, guard semantics, honest status labels | +| [reference/review-modes.md](csreview/reference/review-modes.md) | The five built-in code-review methodologies | +| [reference/reports.md](csreview/reference/reports.md) | What the generated reports actually contain + the canonical finding schema | -Examples of global skill directories: +## Installation for AI agents -- Codex: `~/.codex/skills/csreview` or `~/.agents/skills/csreview` -- Trae / SOLO: `~/.trae/skills/csreview` -- Claude Code: `~/.claude/skills/csreview` - -Do not create project-local agent folders or instruction files such as `/.trae/skills/csreview`, `/.codex/skills/csreview`, `/AGENTS.md`, `/CLAUDE.md`, `.cursorrules`, or `.windsurfrules` solely to install CSReview. Those are allowed only when the user deliberately chooses project-scoped installation. The audited project should contain its own source code plus generated report artifacts such as `csreview-reports/_security-report.html`, which are ignored by Git. - -### Semgrep is Mandatory for Agent Analysis - -Every CSReview run must attempt to call **Semgrep** as the baseline SAST layer: - -```bash -semgrep --version -semgrep --config auto --json --quiet -``` - -If Semgrep is unavailable, the report must explicitly mark the run as lower-confidence Agent-Only analysis and tell the user how to install Semgrep. Semgrep is declared in the package metadata as a required external tool because the official distribution is a CLI installed with `pipx`, `uv`, Homebrew, Docker, or platform package managers rather than as a normal npm dependency. - -For dependency analysis, CSReview also attempts read-only SCA checks when available: -- `npm audit --json` for npm lockfiles and `pnpm audit --json` for `pnpm-lock.yaml` -- `osv-scanner scan --format json ` for multi-ecosystem dependency vulnerability scanning - -Framework-native linters and scanners such as ESLint security plugins, pip-audit, Bandit, Gosec, cargo audit, dotnet vulnerable package checks, Checkov, Hadolint, Trivy, and Snyk should be called when relevant to the detected stack. - -### Stack-Native Tool Recommendation Matrix - -After detecting the workspace stack, CSReview selects read-only tools that are native or commonly recommended for that ecosystem. Run a tool only if it is already available in the user's environment or already configured in the workspace. Do not install missing tools inside the analyzed project. If a tool is unavailable, the report records it as a `missing recommended tool`. - -| Detected stack | Prefer read-only commands and scanners | -| --- | --- | -| JavaScript / TypeScript / React / Node | `npm audit --json` for npm lockfiles, `pnpm audit --json` for `pnpm-lock.yaml`, configured `eslint`, `eslint-plugin-security`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `typescript-eslint`, Semgrep | -| .NET / C# / ASP.NET | `dotnet build --no-restore`, `dotnet format analyzers --verify-no-changes`, `dotnet package list --include-transitive --vulnerable --format json` or `dotnet list package --include-transitive --vulnerable --format json`, Roslyn analyzers, Semgrep | -| Kotlin / Android / JVM | `gradlew lint` or `./gradlew lint`, Android Lint, `detekt`, `ktlint`, Qodana, Gradle dependency checks, OSV-Scanner, Semgrep | -| Go | `go vet ./...`, `govulncheck ./...`, `gosec ./...`, `staticcheck ./...`, `golangci-lint run`, OSV-Scanner, Semgrep | -| Python | `pip-audit`, `bandit -r`, `ruff check`, `safety`, OSV-Scanner, Semgrep | -| Java / Spring | Maven/Gradle dependency checks, SpotBugs/FindSecBugs when configured, Checkstyle/PMD when configured, Qodana, OSV-Scanner, Semgrep | -| Rust | `cargo audit`, `cargo deny check`, `cargo clippy --all-targets --all-features`, OSV-Scanner, Semgrep | -| PHP / Ruby / Flutter | `composer audit`, PHPStan/Psalm, `bundle audit`, Brakeman, `dart analyze`, `flutter analyze`, OSV-Scanner, Semgrep | -| IaC / containers / BaaS | Checkov, Trivy, Hadolint, Terraform validators, Supabase/Firebase/Appwrite rule validation when configured, Semgrep | - -### External Research is Mandatory When Uncertain - -Every coding agent using CSReview must research externally when it is unsure about framework behavior, security defaults, dependency advisories, CVE details, exploitability, or safe remediation. The expected source order is: - -- official framework documentation, release notes, migration guides, and security pages -- vendor security advisories for the affected product, database, cloud service, BaaS, package manager, or SDK -- specialized security references such as OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, and Snyk - -Do not guess. If external sources disagree or the exact version cannot be confirmed, CSReview must mark the finding as lower confidence and explain the uncertainty in the report. - -No-findings results are not proof that a system is secure. Reports must state that a clean run only means CSReview and the available external tools did not detect reportable issues in the analyzed scope. - -### Report Handoff - -After every run, CSReview must show the user: - -- **Agent name prefix**: report filenames begin with the coding agent name, for example `csreview-reports/codex_security-report.html` and `csreview-reports/codex_security-findings.md`. Other agents replace `codex` with their own name. -- Generic names such as `security-report.html`, `security-findings.md`, `csreview-report.html`, and `csreview-report.md` are invalid because they hide which agent produced the analysis. -- Use `--agent-name ` or `CSREVIEW_AGENT_NAME=` so each agent writes its own report files. -- **HTML report path**: `csreview-reports/_security-report.html` or the configured output HTML file, for the user to click/open in a browser. -- **Markdown report path**: `csreview-reports/_security-findings.md` or the configured output Markdown file, for the coding agent to read before planning remediation. - -The verbal summary is not enough for implementation. A coding agent must analyze the Markdown report and then inspect the referenced source files, schemas, tests, framework documentation, and security advisories before proposing or applying changes. - -### Optional Local DAST Complement - -After the user or coding agent implements and validates remediations from the static report, CSReview can optionally run a complementary Local DAST report against a local test environment only. This is never automatic and never allowed against production. - -Use it only when: - -- the user explicitly confirms the test; -- the target is `localhost` or `127.0.0.1`; -- `.env`, `.env.local`, and `.env.development` do not point to external services; -- any database copy used for testing was deliberately made, stored in a secure local place, and sanitized or minimized where needed; -- the goal is White Hat Hacker-style analysis and remediation of security flaws. +Install CSReview as a **global agent skill** — never inside the audited project: -```bash -csreview . --local-dast-url http://localhost:3000 --confirm-local-dast --agent-name codex -``` - -The complementary files are written to `csreview-reports/_local-dast-report.html` and `csreview-reports/_local-dast-findings.md`. - -### Why This Exists - -Security vulnerabilities cost companies billions annually. Most development teams lack dedicated security engineers to review code before deployment. With the rise of **vibe coding** (non-technical users building software with AI agents), security risks have multiplied. CSReview bridges this gap by providing: - -1. **Development-Time Security Alignment**: Goes beyond basic linting with static source/config review, Semgrep/SCA evidence, and a security consultant's adversarial reasoning without probing live systems -2. **Dual Report System**: - - **HTML Report** in the user's language for human understanding - - **Markdown Report** in English for AI coding agents to parse and plan remediations without changing the audited code automatically -3. **Universal Compatibility**: Works with any AI coding agent (Trae, OpenCode, Qwen CLI, Codex, Claude Code, Antigravity, Qoder, Cursor, Windsurf, Cline, GitHub Copilot CLI, Aider, Continue, DevChat) -4. **Multi-Platform Coverage**: Analyzes code for macOS, iOS, Linux, Windows, web, mobile, and backend systems -5. **Vibe Coding Protection**: Specifically detects vulnerabilities commonly introduced by AI-generated code -6. **Compliance Verification**: Checks against LGPD, GDPR, SOC 2, HIPAA, CCPA/CPRA requirements -7. **Database Security**: Deep analysis of SQL, NoSQL, and BaaS platform configurations -8. **Supply Chain Security**: SLSA 3 framework verification -9. **OWASP ASVS**: Systematic verification against V1-V14 categories - -### Real-World Use Cases - -- **Pre-release security gate**: Run before release while reviewing only the local workspace -- **Code review enhancement**: Augment human code reviews with automated security analysis -- **Legacy code audit**: Identify vulnerabilities in existing codebases -- **Compliance preparation**: Find issues before security audits (SOC 2, ISO 27001, LGPD/GDPR) -- **Vibe coding verification**: Check AI-generated code for common security anti-patterns -- **Database security audit**: Verify RLS policies, access controls, and configurations -- **CI/CD integration**: Can be triggered in automated pipelines via AI agents -- **Learning tool**: Understand vulnerability patterns and secure coding practices - -## Features - -### 8 Default Phases + Optional Local DAST - -| Phase | Name | Description | -|-------|------|-------------| -| 0 | **Tool Detection** | Require a Semgrep attempt, detect framework-native linters/scanners (eslint, npm/pnpm audit, bandit, trivy, snyk, gosec, codeql, etc.), and use available tools for real file-by-file scanning | -| 1 | **Reconnaissance** | Project structure scan, secret detection, external service mapping | -| 2 | **Ultra-Deep Security** | Injection, auth, data leakage, XSS/CSRF, config, deps, cloud, .NET, Delphi/Lazarus, Go, DLL/installer, platform-specific, logic flaws | -| 3 | **Database Security** | SQL/NoSQL/BaaS structure analysis, Firebase cost & performance, access patterns | -| 4 | **SLSA 3 Supply Chain** | Source integrity, build integrity, dependency security, deployment security | -| 5 | **OWASP ASVS** | V1-V14 verification categories (Architecture, Auth, Session, Access, Crypto, etc.) | -| 6 | **Compliance** | LGPD, GDPR, SOC 2 Type II, HIPAA, CCPA/CPRA regulatory analysis | -| 7 | **Vibe Coding** | Static heuristics for vulnerability patterns commonly seen in rushed or AI-assisted code | -| 8 | **Report Generation** | HTML (user language) + MD (English for agents) dual report system | -| 9 | **Optional Local DAST** | Complementary post-remediation local-only dynamic checks against `localhost`/`127.0.0.1` after explicit user confirmation | - -### Analysis Modes - -CSReview operates in one of three engine modes depending on the deterministic tools it can invoke and parse: - -| Mode | Tools Installed | Accuracy | Confidence | Recommended For | -|------|----------------|----------|------------|-----------------| -| **Self-Hosted** | All relevant engine-orchestrated tools available locally | Highest | CONFIRMED/TOOL-ONLY | Local release gates, compliance prep | -| **Hybrid** | Some engine-orchestrated tools available | High | Mixed CONFIRMED + TOOL-ONLY + heuristic | Development, CI/CD | -| **Agent-Only** | No engine-orchestrated tools available | Lower | Heuristic only | Quick checks, learning | - -**Engine-Orchestrated Tools:** -| Tool | Engine behavior | -|------|-----------------| -| **Semgrep** | Invoked and parsed as SAST baseline | -| **Node package audit** | Invoked and parsed for Node.js dependency advisories using `pnpm audit` for `pnpm-lock.yaml` or `npm audit` for npm lockfiles | -| **OSV-Scanner** | Invoked and parsed for multi-ecosystem dependency advisories | -| **Local DAST** | Optional post-remediation local-only complement with separate reports | - -**Agent-Recommended Stack-Native Tools:** -Bandit, Trivy, Snyk, Gosec, ESLint security plugins, CodeQL, pip-audit, cargo audit, dotnet vulnerable package checks, Checkov, Hadolint, Brakeman, Grype, RetireJS, Safety, and OWASP Dependency-Check are recommended when relevant to the detected stack. They are not parsed by the npm engine unless explicitly added to the engine-orchestrated list, so their results should be treated as supplemental evidence in agent reports. - -### Built-in Code Review System - -CSReview includes a complete code review system - no additional skills or plugins required: - -| Mode | Command | Description | -|------|---------|-------------| -| **Standard Review** | `@csreview review [files]` | Code quality, architecture, performance, testing, documentation | -| **Adversarial Review** | `@csreview adversarial [files]` | Red-team mindset: boundary conditions, failure modes, edge cases | -| **Security Review** | `@csreview security-review [files]` | Security-focused review with vulnerability detection | -| **Request Review** | `@csreview request-review [scope]` | Review of PR/branch/commit with change-type detection | -| **Remediation Planning** | `@csreview review csreview-reports/codex_security-findings.md` | Parse the report, understand context, and plan fixes for a human or coding agent to apply deliberately | - -### Analysis Capabilities - -| Category | Coverage | -|----------|----------| -| **Injection** | SQL, NoSQL, Command, LDAP, XPath, Template (SSTI) | -| **Authentication** | JWT, Session, RLS Policies, OAuth, IDOR, Privilege Escalation | -| **Data Leakage** | Log exposure, PII, Stack traces, Debug mode, Cache | -| **Cross-Site** | XSS (Reflected/Stored/DOM), CSRF, CORS, Clickjacking | -| **Configuration** | Security headers, TLS/SSL, File uploads, Rate limiting | -| **Dependencies** | CVEs, Supply chain, Typosquatting, License compliance | -| **Cloud/Backend** | Supabase (RLS, Storage), Firebase (Rules, Auth), Appwrite, Neon, PocketBase, Convex | -| **Database Security** | PostgreSQL, MySQL, MariaDB, SQL Server, Firebird, SQLite, Oracle, MongoDB, Redis, CouchDB, DynamoDB, Cassandra | -| **Cost Analysis** | Firebase Firestore/RTDB/Storage/Functions cost estimation, unbounded query detection, trigger cost analysis | -| **.NET** | ASP.NET Core, Blazor, EF Core, NuGet security, assembly signing, BinaryFormatter | -| **Delphi/Lazarus** | VCL, FMX, LCL, FireDAC, dbExpress, IBX, FIBPlus, zeoslib, Firebird connectivity | -| **Go** | Gin, Echo, Fiber, GORM, govulncheck, CGo boundary, unsafe.Pointer | -| **Binary/Installer** | DLL hijacking, ASLR/DEP, code signing, Inno Setup, NSIS, WiX, MSI, Authenticode | -| **Platform-Specific** | macOS, iOS, Linux, Windows native vulnerabilities | -| **System-Level** | Path traversal, Symlinks, IPC, Memory corruption, TOCTOU | -| **Business Logic** | Race conditions, Mass assignment, Deserialization flaws | -| **Supply Chain** | SLSA 3: Signed commits, build provenance, SBOM, artifact signing | -| **Compliance** | LGPD, GDPR, SOC 2, HIPAA, CCPA/CPRA gap analysis | -| **Vibe Coding** | Static boolean heuristic for patterns commonly seen in rushed or AI-assisted code; it does not prove AI authorship | - -### Supported Technologies - -#### Languages & Frameworks -- **Frontend**: React, Vue, Nuxt, Angular, Svelte, Next.js -- **Mobile**: Flutter, Kotlin (Android), Swift (iOS), React Native -- **Backend**: Python, Node.js, C#, Go, Java, PHP, Ruby -- **Systems**: C, C++, Rust -- **Desktop**: Electron, Tauri, native apps -- **.NET Ecosystem**: .NET Framework, .NET Core, .NET 5/6/7/8/9, ASP.NET Core, Blazor, MAUI, WPF, WinForms, Xamarin -- **Delphi/Lazarus**: Delphi (VCL, FMX), Lazarus (LCL), Free Pascal, Object Pascal -- **Go**: Go standard library, Gin, Echo, Fiber, GORM, and Go modules - -#### Installer & Binary Security -- **DLL Analysis**: DLL hijacking, side-loading, missing ASLR/DEP, unsigned DLLs -- **Installers**: Inno Setup, NSIS, WiX, InstallShield, MSI packages -- **Binary Security**: Code signing, Authenticode, checksum integrity -- **Package Formats**: NuGet, Chocolatey, WinGet, DEB, RPM, APK, IPA, DMG - -#### Databases & Backends -- **SQL**: PostgreSQL, MySQL, MariaDB, SQL Server, Firebird, SQLite, Oracle -- **NoSQL**: MongoDB, Redis, CouchDB, DynamoDB, Cassandra, ArangoDB -- **BaaS**: Supabase, Firebase, Appwrite, AWS Amplify, Nhost, Neon, PocketBase, Convex, PlanetScale, Turso - -#### AI Agent Compatibility - -| Agent | Integration Method | -|-------|-------------------| -| **Trae / SOLO** | Global skill via `~/.trae/skills/csreview/SKILL.md` | -| **OpenCode** | Compatible via global agent instructions | -| **Qwen CLI** | Compatible via system prompt injection | -| **Codex** | Global skill via `~/.codex/skills/csreview/SKILL.md` or `~/.agents/skills/csreview/SKILL.md` | -| **Claude Code** | Global skill via `~/.claude/skills/csreview/SKILL.md` | -| **Antigravity** | Compatible via global agent configuration | -| **Qoder** | Compatible via agent configuration | -| **Cursor / Windsurf / Cline** | Compatible via global rules/instructions when supported | -| **GitHub Copilot CLI** | Compatible via global/custom instructions when supported | -| **Aider / Continue / DevChat** | Compatible via global agent conventions when supported | - -### Output Reports - -1. **`csreview-reports/_security-report.html`** - Visual dashboard for humans (in user's language) - - Security score (0-100) - - SLSA Level indicator - - OWASP ASVS compliance percentage - - Regulatory compliance status (LGPD/GDPR/SOC2/HIPAA/CCPA) - - Vibe Coding Risk indicator - - Severity distribution charts - - Database security findings - - Compliance matrix - - Detailed findings with code snippets - - Exploitation scenarios - - Recommended fixes with corrected code - - OWASP/CWE references - -2. **`csreview-reports/_security-findings.md`** - Structured report for AI agents (always in English) - - Machine-readable findings - - Exact file paths and line numbers - - Vibe-risk heuristic flags, not deterministic authorship scoring - - Compliance mapping per finding - - Database security findings (SQL/NoSQL/BaaS) - - SLSA assessment - - OWASP ASVS compliance table - - Compliance matrix (LGPD/GDPR/SOC2/HIPAA/CCPA) - - Vulnerable code blocks - - Corrected code ready to apply - - Fix priority order - - Agent execution instructions - -## Installation - -### For AI Agents - -Install CSReview from outside the project you want to audit. Do not clone or copy the skill into the target project's `.trae`, `.codex`, `.agents`, `.claude`, or instruction-file locations unless the user explicitly requested local project installation. - -1. Clone this repository into a tools/downloads location: ```bash git clone https://github.com/decksoftware/csreview.git -cd csreview -``` - -2. Copy the skill to your agent's global skills directory: -```bash +# Claude Code +mkdir -p ~/.claude/skills/csreview && cp -r csreview/csreview/* ~/.claude/skills/csreview/ # Codex -mkdir -p ~/.codex/skills/csreview -cp -R csreview/. ~/.codex/skills/csreview/ - -# Codex alternate global skill root -mkdir -p ~/.agents/skills/csreview -cp -R csreview/. ~/.agents/skills/csreview/ - +mkdir -p ~/.codex/skills/csreview && cp -r csreview/csreview/* ~/.codex/skills/csreview/ # Trae / SOLO -mkdir -p ~/.trae/skills/csreview -cp -R csreview/. ~/.trae/skills/csreview/ - -# Claude Code -mkdir -p ~/.claude/skills/csreview -cp -R csreview/. ~/.claude/skills/csreview/ -``` - -PowerShell example: -```powershell -git clone https://github.com/decksoftware/csreview.git -Set-Location .\csreview -New-Item -ItemType Directory -Force "$env:USERPROFILE\.codex\skills" | Out-Null -New-Item -ItemType Directory -Force "$env:USERPROFILE\.codex\skills\csreview" | Out-Null -Copy-Item -Recurse -Force .\csreview\* "$env:USERPROFILE\.codex\skills\csreview" +mkdir -p ~/.trae/skills/csreview && cp -r csreview/csreview/* ~/.trae/skills/csreview/ ``` -3. The globally installed skill will be automatically detected and can be invoked with: - - `@csreview` - - "Run a security review on this project" - - "Check for vulnerabilities" - - "Do a pentest analysis" - - "Verify LGPD and GDPR compliance" - - "Check if my code has vibe coding vulnerabilities" - -### External Security Tools - -CSReview works standalone, but installing external tools enhances accuracy and provides additional validation layers. When Semgrep, OSV-Scanner, and the relevant Node package audit tool are available, CSReview can operate in **Self-Hosted** engine mode; otherwise it reports **Hybrid** or **Agent-Only** based on the parsed tools available. The npm package declares these tools in its `csreview` metadata: - -- Required external tool: `semgrep` -- Recommended external tools: `osv-scanner`, `npm audit`, `pnpm audit` - -#### Semgrep (Required Baseline) - -**Semgrep** is the primary external SAST tool used by CSReview. Agents must attempt to run it on every audit. It provides advanced static analysis rules across 30+ languages and significantly improves detection accuracy. +Then install the CLI globally (`npm install -g ./csreview` from the repo root) so every agent can invoke the same deterministic engine. To update: `git pull` and repeat. The engine's read-only pre-flight tells you when a newer version exists in the official repository (skip with `--no-update-check`); it never auto-updates. -**Why install Semgrep?** -- Validates CSReview findings with industry-standard SAST rules -- Detects patterns that regex-based scanning may miss -- Provides CONFIRMED/TOOL-ONLY confidence level for findings -- Community rules cover OWASP Top 10, CWE, and framework-specific issues -- Free tier available for local scanning +## How a run flows -**Installation:** - -```bash -# pipx (recommended isolated install) -pipx install semgrep - -# uv tool install -uv tool install semgrep - -# Homebrew (macOS/Linux) -brew install semgrep - -# Docker -docker pull semgrep/semgrep -``` - -**Verify installation:** -```bash -semgrep --version -# Expected output: X.Y.Z - -semgrep --config auto --json --quiet . -# Verifies Semgrep can access community rules ``` - -**Important:** Semgrep must be available in the system PATH for CSReview to detect it globally. After installation, verify it's accessible from any directory: -```bash -# Open a NEW terminal and run: -where semgrep # Windows -which semgrep # macOS/Linux -semgrep --version +csreview --agent-name + └─ scan workspace (recursive, monorepo-aware, generated caches excluded) + └─ run engine-orchestrated tools in parallel (Semgrep · package audit · OSV-Scanner [· Gitleaks/Trivy/gosec/Bandit]) + └─ heuristic detector pass (secrets redacted, config rules scoped to config files) + └─ merge subagent partials (when present) and deduplicate by file:line:CWE + └─ multi-source evidence -> CONFIRMED + └─ suppress noise (.csreview-ignore + built-in generated-cache defaults) and apply --baseline + └─ score (severity-capped: any CRITICAL caps at 49, any HIGH at 74) + └─ write reports: _security-report.html · _security-findings.md · _security.sarif + └─ exit code: 0, or 1 when --fail-on is hit (CI gate) ``` -If `semgrep` is not found in PATH after installation: -- **Windows**: Add the Python Scripts directory to PATH (e.g., `C:\Users\\AppData\Local\Programs\Python\PythonXX\Scripts\`) -- **macOS/Linux**: Ensure `~/.local/bin` or the pip install location is in your `$PATH` - -#### OSV-Scanner (Recommended SCA Complement) - -**OSV-Scanner** complements Semgrep by checking dependency manifests and lockfiles against the OSV vulnerability database. Semgrep answers "is this code pattern dangerous?"; OSV answers "is this dependency/version known vulnerable?" - -**Installation:** - -```bash -# Windows -winget install Google.OSVScanner - -# macOS/Linux with Homebrew -brew install osv-scanner - -# Go install -go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest -``` - -**Verify and scan:** - -```bash -osv-scanner --version -osv-scanner scan --format json . -``` - -CSReview only uses OSV-Scanner in scan/report mode. It does not run OSV guided remediation or any dependency update command. - -**Other Supported Tools:** - -| Tool | Install Command | Purpose | -|------|----------------|---------| -| OSV-Scanner | `winget install Google.OSVScanner` / `brew install osv-scanner` | Multi-ecosystem dependency vulnerability scanning | -| Bandit | `pip install bandit` | Python security linter | -| Trivy | `brew install trivy` / [docs](https://aquasecurity.github.io/trivy/) | Vulnerability + misconfig scanner | -| Snyk | `npm install -g snyk` | Dependency vulnerabilities | -| Gosec | `go install github.com/securego/gosec/v2/cmd/gosec@latest` | Go security linter | -| pip-audit | `pip install pip-audit` | Python dependency audit | -| cargo audit | `cargo install cargo-audit` | Rust dependency audit | -| Checkov | `pip install checkov` | Infrastructure-as-code security | -| Hadolint | `brew install hadolint` / `docker pull hadolint/hadolint` | Dockerfile security | - -CSReview automatically detects which tools are installed and adjusts its analysis mode accordingly. If Semgrep is missing, CSReview continues only as a lower-confidence report and clearly flags that limitation. - -### Manual Invocation - -Simply ask your AI coding assistant: -> "Use the csreview skill to analyze this project for security vulnerabilities" - -## Usage Examples - -### Basic Security Scan -``` -@csreview -``` - -### Targeted Analysis -``` -@csreview Check specifically for SQL injection and authentication flaws -``` - -### Pre-Deployment Review -``` -@csreview Run a full local workspace security review before release -``` - -### Backend Security -``` -@csreview Analyze my Supabase backend for RLS policy gaps and data leakage -``` - -### Database Security -``` -@csreview Check my PostgreSQL and MongoDB database security configurations -``` - -### Compliance Verification -``` -@csreview Verify LGPD and GDPR compliance in my codebase -``` - -### Vibe Coding Check -``` -@csreview Check if my code has vibe coding vulnerabilities from AI-generated code -``` - -### Supply Chain Security -``` -@csreview Check supply chain security (SLSA level) -``` - -### OWASP ASVS Verification -``` -@csreview Run OWASP ASVS verification on this project -``` - -### Mobile App Security -``` -@csreview Check this Flutter app for iOS and Android security issues -``` - -### Standard Code Review -``` -@csreview review src/auth.ts src/middleware/ -``` - -### Adversarial Review (Red Team) -``` -@csreview adversarial src/api/payments/ -``` - -### Request Review of Changes -``` -@csreview request-review main..feature/auth -``` - -### Plan Remediation from Report -``` -@csreview review csreview-reports/codex_security-findings.md -``` - -## Severity Classification - -| Severity | Criteria | Response Time | -|----------|----------|---------------| -| **Critical** | Direct data breach, RCE, auth bypass, exposed PII | Immediate | -| **High** | Significant vulnerability, exploitable with effort | 24-48h | -| **Medium** | Moderate risk, requires specific conditions | 1 week | -| **Low** | Minor issue, defense-in-depth improvement | Next sprint | -| **Info** | Best practice recommendation | Consider | - -## How It Works - -``` -CSReview Workflow (8 Phases) - -Phase 1: Reconnaissance & Mapping - - Project structure scan - - Technology identification - - Secret detection - - External service mapping - -Phase 2: Ultra-Deep Security Analysis - - Injection vulnerability checks - - Authentication & authorization review - - Data leakage analysis - - Cross-site vulnerability scan - - Configuration security audit - - Dependency vulnerability check - - Cloud/Backend security review - - Platform-specific checks (macOS/iOS/Linux/Win) - - Business logic flaw analysis - -Phase 3: Database Security Analysis - - SQL database structure and query security - - NoSQL database configuration and injection checks - - BaaS platform security (Supabase, Firebase, Appwrite, Neon, etc.) - - Access control and encryption verification - -Phase 4: SLSA 3 Supply Chain Security - - Source integrity (signed commits, branch protection) - - Build integrity (CI/CD, provenance, signing) - - Dependency security (lock files, pinning, SBOM) - - Deployment security (env separation, secret management) - -Phase 5: OWASP ASVS Verification - - V1-V14 systematic verification - - Architecture, Auth, Session, Access, Validation - - Crypto, Error handling, Data protection - - Communication, Business logic, API security - -Phase 6: Regulatory Compliance Analysis - - LGPD (Brazil) - - GDPR (EU) - - SOC 2 Type II - - HIPAA (US Health) - - CCPA/CPRA (California) - -Phase 7: Vibe Coding Heuristics - - Static vulnerability patterns commonly seen in rushed or AI-assisted code - - Boolean vibe-risk flags, not authorship proof - - Common insecure AI-assisted development anti-pattern identification - -Phase 8: Report Generation - - HTML report (user language) for human review - - Markdown report (English) for human/coding-agent remediation planning -``` +After remediation, an optional Phase 9 local-only probe (`--local-dast-url http://localhost:3000 --confirm-local-dast`) checks security headers and CORS against your loopback dev server, with hard engine guards (loopback-only targets, no redirects followed, reports written only inside `csreview-reports/`). ## Contributing -Contributions are welcome! Please feel free to submit a Pull Request. - -### Areas for Contribution -- Additional vulnerability detection patterns -- Support for more languages/frameworks -- Enhanced report formatting -- CI/CD integration examples -- Documentation improvements -- Additional compliance frameworks -- Database-specific security checks +Issues and PRs are welcome at [decksoftware/csreview](https://github.com/decksoftware/csreview). High-leverage areas: detector precision tests (safe/unsafe pairs per pattern), language-specific rules beyond the current six, additional engine-orchestrated tool normalizers, and report UX. Every PR runs lint, typecheck, the full test suite on 3 OSes, a Semgrep scan, and a dogfood self-scan gated with `--fail-on high`. ## License -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +MIT — see [LICENSE](LICENSE). ## Acknowledgments -- Deck Software -- Márcio PS, idealizer of CSReview -- Claude Code, Trae, MiniMax, Qwen, Cascade da Windsurf, Codex, GLM 5.1, MiMo V2.5 Pro, and other AI reviewer agents/tools that contributed ideas, review, and assistance -- OWASP Top 10 - https://owasp.org/www-project-top-ten/ -- OWASP ASVS - https://owasp.org/www-project-application-security-verification-standard/ -- SLSA Framework - https://slsa.dev/ -- CWE Database - https://cwe.mitre.org/ -- Security research community worldwide +CSReview is a **Deck Software** project idealized by **Márcio PS**, built with assistance, review, and ideas from AI coding agents and tools including Claude Code, Trae, MiniMax, Qwen, Cascade, Codex, GLM, MiMo, and other reviewer agents — plus the open-source scanners it orchestrates: Semgrep, OSV-Scanner, Gitleaks, Trivy, gosec, and Bandit. ## Support -- **Issues**: [GitHub Issues](https://github.com/decksoftware/csreview/issues) -- **Discussions**: [GitHub Discussions](https://github.com/decksoftware/csreview/discussions) - ---- - -**Made with secure software development in mind** +Open an issue at https://github.com/decksoftware/csreview/issues. Reports never embed raw secrets (evidence is redacted), but review any report before attaching it publicly: it intentionally contains your project's file paths and finding locations. diff --git a/csreview/SKILL.md b/csreview/SKILL.md index 5db8d5d..f366389 100644 --- a/csreview/SKILL.md +++ b/csreview/SKILL.md @@ -5,9 +5,16 @@ description: "Development-time local workspace security alignment for codebases. # CSReview - Code Security Review -## Overview +## What CSReview Is -This skill performs development-time security alignment for the local workspace a developer is actively building. It applies a penetration tester's adversarial mindset to the project's local source, configuration, dependencies, and infrastructure files (static SAST + SCA). It does NOT perform live penetration testing against running, deployed, or production systems. It identifies vulnerabilities, data leakage risks, misconfigurations, and security flaws, then generates: +CSReview performs development-time security alignment for the local workspace a developer is actively building. It applies a penetration tester's adversarial mindset to the project's local source, configuration, dependencies, and infrastructure files (static SAST + SCA). It does NOT perform live penetration testing against running, deployed, or production systems. + +It is two things working together, and the agent must keep them straight: + +1. **A deterministic engine** (the `csreview` CLI). It discovers the workspace, runs and parses the external security tools, applies its own heuristic detector, deduplicates evidence across sources (promoting corroborated findings to `CONFIRMED`), scores the result, and writes ALL report files. The engine is the single writer of reports. +2. **An agent methodology** (this document + `reference/`). The agent runs the engine, then adds what tools cannot: contextual review of flagged code, framework research, remediation planning, and honest communication of confidence and limits. + +CSReview's value is orchestration, corroboration, and evidence — it complements Semgrep and the other scanners; it does not replace them. Its built-in regex detector is a complementary net (secrets, misconfigurations, BaaS rules, common injection shapes), not a taint-tracking SAST. ## Scope @@ -18,1931 +25,223 @@ This skill performs development-time security alignment for the local workspace ## Ethical Use & Attribution -CSReview is a white-hat security alignment tool. You may copy, fork, adapt, and replicate it under the MIT License, but the project asks that it be used for good: authorized security reviews, local development hardening, education, and remediation work in the spirit of an ethical hacker / White Hat Hacker. Do not use CSReview to support unauthorized intrusion, exploitation, credential theft, data exfiltration, surveillance, or harm. - -Credit should be preserved where practical: CSReview is a Deck Software project idealized by Márcio PS, built with assistance, review, and ideas from AI coding agents and tools including Claude Code, Trae, MiniMax, Qwen, Cascade da Windsurf, Codex, GLM 5.1, MiMo V2.5 Pro, and other reviewer agents. - -1. **HTML Report** (`csreview-reports/_security-report.html`) - Visual report for human review with executive summary, charts, and detailed findings -2. **Markdown Report** (`csreview-reports/_security-findings.md`) - Structured report for humans and coding agents to understand, prioritize, and plan remediations without CSReview modifying the audited code -3. **SARIF Report** (`csreview-reports/_security.sarif`) - SARIF 2.1.0 for CI pipelines and GitHub code scanning ingestion. It never embeds raw vulnerable code, so secrets are not leaked into the uploaded artifact. - -**CSReview is READ-ONLY**: It never modifies, deletes, moves, or creates source code in the analyzed project. It only identifies problems, locates them precisely, and suggests remediation approaches based on the frameworks and technologies in use. The actual fixes are applied later by the human developer or a coding agent after understanding the project context, schema, tests, and regression risk. When encountering unfamiliar frameworks, CSReview researches official documentation and community forums to provide accurate recommendations. - -**Global Skill Installation Policy**: CSReview is a global agent skill. It MUST be installed and loaded from the agent's global skills/instructions environment, such as `~/.codex/skills/csreview`, `~/.agents/skills/csreview`, `~/.trae/skills/csreview`, or `~/.claude/skills/csreview`. The agent MUST NOT copy, scaffold, install, update, delete, or move the CSReview skill inside the project being audited, including `/.trae/skills/csreview`, `/.codex/skills/csreview`, `/.agents/skills/csreview`, `/.claude/skills/csreview`, `/AGENTS.md`, `/CLAUDE.md`, `.cursorrules`, or `.windsurfrules`, unless the user explicitly asks for project-local installation. Generated reports may be written to the selected output directory, but those reports are audit artifacts, not a skill installation. Likewise, opt-in tool provisioning (`--provision-tools`) writes only verified tool binaries into an isolated, gitignored `.csreview/` workspace inside the project — that is a local tool cache, not a skill installation and not a modification of the audited source. - -**Semgrep is mandatory as a baseline SAST attempt**: every CSReview run MUST attempt to execute `semgrep --version` and `semgrep --config auto --json --quiet ` before relying on agent-only analysis. Semgrep is a required external CLI tool, not a normal bundled npm dependency; install it with `pipx install semgrep`, `uv tool install semgrep`, Homebrew, Docker, or the platform package manager. If Semgrep is unavailable, the report MUST state that the run has lower confidence and include installation instructions. - -**Dependency SCA complements Semgrep**: when available, the deterministic npm engine orchestrates and parses Node package audit tools selected by lockfile: `npm audit --json` for npm lockfiles, `pnpm audit --json` for `pnpm-lock.yaml`, and `bun audit --json` for `bun.lockb`/`bun.lock` (npm/pnpm take priority when more than one lockfile is present). It also parses `osv-scanner scan --format json ` for multi-ecosystem lockfile/manifests. These tools complement Semgrep by identifying known vulnerable dependency versions without changing source code or package files. Framework-native lint/scanning tools such as ESLint security plugins, pip-audit, Bandit, Gosec, cargo audit, dotnet vulnerable package checks, Checkov, Hadolint, Trivy, Snyk, and CodeQL are agent-recommended stack-native tools: the agent may run them when relevant and available, but they are not parsed by the npm engine unless explicitly added to the engine-orchestrated tool list. - -**Config and BaaS misconfiguration detection**: on files classified as configuration/IaC/BaaS (Firebase/Firestore/Storage rules, SQL migrations, Dockerfiles, Kubernetes/Compose YAML, Terraform, ORM config), CSReview additionally checks for high-signal misconfigurations such as public BaaS rules (`allow ... if true`), disabled Row Level Security, disabled TLS verification, `0.0.0.0/0` network ingress, public object-storage ACLs, privileged/run-as-root containers, world-writable permissions, and unpinned `:latest` base images. These config patterns are scoped to those file kinds and are not run against application source code, to keep false positives low. - -**CI integration and noise control**: CSReview also emits a SARIF 2.1.0 report (`_security.sarif`) for CI pipelines and code-scanning dashboards. A `.csreview-ignore` file at the project root (gitignore-style globs: `**`, `*`, `?`, anchored `/x`, directory `x/`, and `!negation`) suppresses findings for matching paths in the report only — it is read-only and never modifies the project. A baseline of known findings can be recorded with `--update-baseline` and enforced with `--baseline ` so CI fails only on NEW findings; baseline fingerprints are line-independent so they survive code shifting. - -**Pre-flight checks (read-only, fail-open)**: before a scan CSReview can check whether a newer CSReview version exists in the official repository — this is advisory only, it never auto-updates itself, and the agent/user reviews the change before updating (skip with `--no-update-check`). `--doctor` additionally reports whether the available external scanners are on their latest version, but it never auto-upgrades system tools. These checks only query pinned official hosts over HTTPS (`raw.githubusercontent.com`/`api.github.com` for `decksoftware/csreview`, `pypi.org`, `crates.io`, `registry.npmjs.org`), never block the scan when offline, and never execute fetched content. - -**Opt-in security-tool provisioning (`--provision-tools`)**: CSReview's fidelity and low false-positive rate depend on running real stack-native security tools and corroborating them with the heuristic detector (a finding seen by both a tool and the detector is promoted to CONFIRMED). When the user opts in with `--provision-tools`, CSReview MAY install the tools it needs — but only safely, and the user is always informed before any download. It downloads each tool ONLY from its official release source (Gitleaks `github.com/gitleaks/gitleaks`, Trivy `github.com/aquasecurity/trivy`, gosec `github.com/securego/gosec`, Bandit from PyPI, plus the already-supported Semgrep and OSV-Scanner), VERIFIES the published SHA-256 checksum before the artifact is made executable or run (a mismatch or a non-official host is rejected, never executed), installs into an ISOLATED, gitignored `.csreview/bin/` workspace (never globally, never `sudo`, never as a project dependency, never modifying the audited source), and FAILS OPEN to lower-confidence Agent-Only mode when a tool cannot be provisioned (offline, unsupported platform, etc.). Without the flag, CSReview runs only tools already on the user's PATH and notes the rest as recommended. The report states which tools actually ran versus heuristic-only. +CSReview is a white-hat security alignment tool (MIT License). Use it for authorized security reviews, local development hardening, education, and remediation. Do not use it to support unauthorized intrusion, exploitation, credential theft, data exfiltration, surveillance, or harm. CSReview is a Deck Software project idealized by Márcio PS, built with assistance and review from AI coding agents including Claude Code, Trae, MiniMax, Qwen, Cascade, Codex, GLM, MiMo, and other reviewer agents. -**Stack-Native Tool Recommendation Matrix**: after detecting the languages, frameworks, package managers, and lockfiles in the workspace, CSReview MUST select the relevant read-only tools below. Run a tool only if it is already available in the user's environment, already configured in the workspace, or provisioned with explicit user opt-in (see Opt-in security-tool provisioning above). Do not install missing tools as project dependencies or into the global system, and never modify the audited source. If a recommended tool is unavailable and not provisioned, record it in the report as a `missing recommended tool` with the exact install/documentation pointer. These tools are agent-recommended unless listed under Engine-Orchestrated Tools. +## Core Rules -| Detected stack | Prefer read-only commands and scanners | -| --- | --- | -| JavaScript / TypeScript / React / Node | `npm audit --json` for npm lockfiles, `pnpm audit --json` for `pnpm-lock.yaml`, `npm run lint -- --format json` when configured, `eslint` with project config, `eslint-plugin-security`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `typescript-eslint`, Semgrep | -| .NET / C# / ASP.NET | `dotnet build --no-restore`, `dotnet format analyzers --verify-no-changes`, `dotnet package list --include-transitive --vulnerable --format json` or `dotnet list package --include-transitive --vulnerable --format json`, .NET Roslyn analyzers (`CAxxxx`, `IDExxxx`), Semgrep, CodeQL/default setup when available | -| Kotlin / Android / JVM | `gradlew lint` or `./gradlew lint`, Android Lint, `detekt`, `ktlint`, Qodana, Gradle dependency vulnerability checks, OSV-Scanner, Semgrep | -| Go | `go vet ./...`, `govulncheck ./...`, `gosec ./...`, `staticcheck ./...`, `golangci-lint run`, OSV-Scanner, Semgrep | -| Python | `pip-audit`, `bandit -r`, `ruff check`, `safety` when available, OSV-Scanner, Semgrep | -| Java / Spring / Maven / Gradle | Maven/Gradle dependency checks, SpotBugs/FindSecBugs when configured, Checkstyle/PMD when configured, Qodana, OSV-Scanner, Semgrep | -| Rust | `cargo audit`, `cargo deny check`, `cargo clippy --all-targets --all-features`, OSV-Scanner, Semgrep | -| PHP / Laravel / Symfony | `composer audit --format=json`, PHPStan/Psalm when configured, Laravel Pint for linting, OSV-Scanner, Semgrep | -| Ruby / Rails | `bundle audit`, `brakeman`, RuboCop when configured, OSV-Scanner, Semgrep | -| Flutter / Dart | `dart analyze`, `flutter analyze`, `dart pub outdated --json`, OSV-Scanner, Semgrep | -| IaC / containers / CI | Checkov, Trivy, Hadolint, Dockerfile linting, GitHub Actions linting, Terraform validators, Semgrep | -| BaaS / database rules | Supabase CLI checks when configured, Firebase rules validation when configured, Appwrite/Convex/PocketBase config review, SQL linters when configured, Semgrep | - -**External Research Protocol**: Do not guess when framework behavior, configuration defaults, security controls, exploitability, dependency advisories, CVE details, or remediation guidance are uncertain. The coding agent MUST know how to perform external internet research when necessary and MUST consult primary or specialized sources before reporting a confident recommendation: - -- official framework documentation, release notes, migration guides, and security pages -- Vendor security advisory pages for the affected product, cloud service, database, BaaS, or package manager -- OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, Snyk advisory pages, and other specialized application security portals -- Official package, API, or SDK documentation for the exact version or major version in use +These rules appear once, here, and apply everywhere: -When external research is used, include source names and URLs in the finding references. Prefer official documentation and vendor advisories over generic blog posts. If sources disagree or the version cannot be confirmed, mark the finding as lower confidence and explain the uncertainty in the report. +1. **READ-ONLY**: CSReview never modifies, deletes, moves, or creates source code in the analyzed project. It identifies problems, locates them precisely, and suggests remediation. Fixes are applied later by the developer or a coding agent with project context. Report files under the output directory and the gitignored `.csreview/` tool cache are audit artifacts, not source modifications. +2. **Global Skill Installation**: CSReview is a global agent skill, loaded from the agent's global skills environment (`~/.codex/skills/csreview`, `~/.agents/skills/csreview`, `~/.trae/skills/csreview`, `~/.claude/skills/csreview`). The agent MUST NOT copy, scaffold, install, update, delete, or move the CSReview skill inside the project being audited (including `/.claude/skills/`, `/AGENTS.md`, `/CLAUDE.md`, `.cursorrules`, `.windsurfrules`) unless the user explicitly asks for project-local installation. +3. **Single writer**: the engine writes the final reports. Subagents (when used) write only partial JSON. The agent never handcrafts report files. +4. **No fabricated metrics**: the engine does not compute ASVS coverage percentages, SLSA levels, or per-article compliance verdicts — so the agent must never state them as scan output. Compliance fields are CWE correlation (indicative), not an audited compliance verification. See `reference/compliance-frameworks.md`. +5. **Never expose secrets in chat**: hardcoded credentials found during a scan are referenced in the reports (redacted) — never echoed in the conversation. +6. **No-Findings Assurance Limit**: zero findings is not proof of security; it only means CSReview and the available tools detected nothing reportable in the analyzed scope. Reports state this; so must the agent. +7. **Honest confidence**: every claim carries its source (engine mode, tool, heuristic confidence). When uncertain, research (see External Research Protocol) or say the uncertainty out loud. -**No-Findings Assurance Limit**: A report with zero findings is not proof that the system is secure. It only means CSReview and the available external tools did not detect reportable issues in the analyzed scope. The HTML and Markdown reports MUST state this limitation when no findings are found. +## How to Run the Engine -**Report Handoff Protocol**: After every CSReview run, the agent MUST present two explicit paths: - -- **Agent name prefix**: report filenames MUST begin with the coding agent name in lowercase, for example `codex_security-report.html` and `codex_security-findings.md`. Other agents must replace `codex` with their own name, such as `claude_security-report.html`. -- **MUST NOT generate generic report names**: `security-report.html`, `security-findings.md`, `_security-report.html`, `_security-findings.md`, `csreview-report.html`, and `csreview-report.md` are invalid handoff names because they hide which agent produced the analysis. -- **CLI identity**: pass `--agent-name ` on CLI runs or set `CSREVIEW_AGENT_NAME=` before running CSReview. Examples: `csreview . --agent-name codex`, `csreview . --agent-name claude`, `CSREVIEW_AGENT_NAME=qwen csreview .`. -- **HTML report path**: the absolute path to `csreview-reports/codex_security-report.html` or the configured output HTML file. Tell the user this is the file to click/open in a browser for human reading. If the environment has an available browser-opening tool and the user asked to open it, open the HTML report in the browser. -- **Markdown report path**: the absolute path to `csreview-reports/codex_security-findings.md` or the configured output Markdown file. Tell the user and the coding agent that this is the file the coding agent must analyze before planning any remediation. - -The coding agent must not infer findings from the verbal summary alone. For remediation work, it must read the Markdown report path first, then inspect the referenced source files, framework documentation, schemas, tests, and security advisories before proposing or applying changes. - -**Phase 9: Optional Local DAST Complementary Report**: after the user or coding agent has implemented and validated remediations from the static CSReview report, the agent MUST inform the user that an optional broader local dynamic validation is available. This phase is not part of the default SAST/SCA run and MUST NOT start automatically. It is a conservative local HTTP probe (security headers + CORS checks), NOT a full penetration test; for active probing install and run a dedicated tool such as Nuclei against the confirmed local target. - -The required user-facing prompt is: "Static remediation is complete. You can optionally run CSReview Phase 9 Local DAST in a local test environment only. Never use this against production. If the test uses a database copy, make sure the copy was made deliberately, stored in a secure local place, and sanitized or minimized where needed. This resource is for White Hat Hacker-style analysis and remediation of security flaws; it sends real HTTP requests only to localhost/127.0.0.1 and writes a complementary report. Do you want me to run it? (yes/no)" - -Phase 9 may proceed only when all of these are true: - -- The user gives explicit user confirmation. -- The user understands this is for a local test environment, never production, and that any database copy used for testing must be securely created, stored, and handled. -- The target URL is strictly `http://localhost:`, `https://localhost:`, `http://127.0.0.1:`, `https://127.0.0.1:`, or the IPv6 loopback `http://[::1]:` / `https://[::1]:`. -- The `.env`, `.env.local`, and `.env.development` pre-flight is advisory, not blocking: if an external host is referenced, it is surfaced as a `DAST-SUSPECTED` warning so you verify the local app under test does not proxy probe traffic to that host. A real development `.env` almost always references external services, so this warning by itself does not abort Phase 9; the hard guards below still apply. -- Redirects are not followed. If a response points to an external host, abort Phase 9 immediately. (This is a hard guard enforced in the engine.) -- The complementary reports are written only inside `csreview-reports/` as `csreview-reports/_local-dast-report.html` and `csreview-reports/_local-dast-findings.md`. A run ID is embedded in the report and, when provided, time-stamped history copies are also written inside `csreview-reports/` so re-running Phase 9 after remediation does not overwrite the previous run's evidence. A read-only per-backend local database dump guide (`_db-dump-guide.html`) is also generated to help prepare an isolated local copy before any database-level testing. - -The CLI form is: +The CLI is the canonical execution path — never reimplement its phases by hand: ```bash -csreview . --local-dast-url http://localhost:3000 --confirm-local-dast --agent-name codex +csreview --agent-name +csreview --doctor [target-directory] # tool availability + freshness, no scan +csreview --version ``` -Phase 9 output uses dynamic status labels: - -- `DAST-CONFIRMED`: dynamically reproduced with clear evidence, normally from a dedicated local DAST tool or an explicitly allowed endpoint test. -- `DAST-SUSPECTED`: anomalous local response that requires human review. -- `DAST-CLEAN`: the checked condition passed for the local target. - -Hard limits: never probe external IPs, domains, staging, or production; never follow redirects to external hosts; never write outside `csreview-reports/`; never use destructive payloads; never use DELETE; do not send mutating POST/PUT/PATCH requests unless the user provided an explicit local test endpoint allowlist and confirmed the data mutation risk. The built-in CSReview local DAST mode is conservative and performs non-mutating HTTP checks such as reachability, browser security headers, and CORS behavior. OWASP ZAP or Nikto may be used only when installed, only after the same pre-flight checks and confirmation, and only against the confirmed local target. - -The analysis covers 8 default report sections: Reconnaissance, Ultra-Deep Security, Database Security, SLSA Build L3 (v1.2) Supply Chain, OWASP ASVS 5.0.0, Compliance mapping (LGPD/GDPR/SOC2/HIPAA/CCPA-CPRA — indicative correlation, not an audited compliance verification), Vibe Coding Protection, and Dual Report Generation. These are report sections, not separate executable engine phases. Phase 9 is optional, local-only, post-remediation, and produces a complementary report. - -CSReview includes built-in **Code Review** capabilities (equivalent to codex:review, codex:adversarial-review, code-review, requesting-code-review, receiving-code-review) - no additional skills or plugins required. - -## When to Invoke - -- User requests security review or code audit -- User asks for vulnerability scan or pentest analysis -- User wants to check for data leakage or exposed secrets -- User mentions SQL injection, XSS, auth flaws, or security concerns -- Before release or deployment preparation, while reviewing only the local workspace -- User asks to review Supabase, Firebase, Appwrite, Neon, or similar backend security -- User invokes `@csreview` or mentions CSReview -- User wants compliance verification (LGPD, GDPR, SOC 2, HIPAA) -- User built code with AI agents and wants to verify security (vibe coding check) -- User wants database structure security validation (SQL/NoSQL/BaaS) -- User requests code review (`@csreview review [files]`) -- User requests adversarial review (`@csreview adversarial [files]`) -- User requests security-focused review (`@csreview security-review [files]`) -- User wants to review changes in a PR or branch (`@csreview request-review [scope]`) -- User wants a remediation plan from a report (`@csreview review csreview-reports/codex_security-findings.md`) - -## Supported Technologies - -### Languages & Frameworks -- **Frontend**: React, Vue, Nuxt, Angular, Svelte, Next.js -- **Mobile**: Flutter, Kotlin (Android), Swift (iOS), React Native -- **Backend**: Python, Node.js, C#, Go, Java, PHP, Ruby -- **Systems**: C, C++, Rust -- **Desktop**: Electron, Tauri, native apps -- **.NET Ecosystem**: .NET Framework, .NET Core, .NET 5/6/7/8/9, ASP.NET Core, Blazor, MAUI, WPF, WinForms, Xamarin -- **Delphi/Lazarus**: Delphi (VCL, FMX), Lazarus (LCL), Free Pascal, Object Pascal -- **Go**: Go standard library, Gin, Echo, Fiber, GORM, and Go modules - -### Installer & Binary Security -- **DLL Analysis**: DLL hijacking, side-loading, missing ASLR/DEP, unsigned DLLs, export table inspection -- **Installers**: Inno Setup, NSIS, WiX, InstallShield, MSI packages, custom installers -- **Binary Security**: Code signing verification, Authenticode, checksum integrity, obfuscation review -- **Package Formats**: NuGet (.nupkg), Chocolatey, WinGet, DEB, RPM, APK, IPA, DMG - -### Databases & Backends -- **SQL**: PostgreSQL, MySQL, MariaDB, SQL Server, Firebird, SQLite, Oracle -- **NoSQL**: MongoDB, Redis, CouchDB, DynamoDB, Cassandra, ArangoDB -- **BaaS**: Supabase, Firebase, Appwrite, AWS Amplify, Nhost, Neon, PocketBase, Convex, PlanetScale, Turso - -### Operating Systems -- **macOS**: App Sandbox, Keychain, TCC, plists, XPC, Gatekeeper -- **iOS**: URL schemes, Keychain, jailbreak detection, TLS, ATS, biometrics -- **Linux**: SUID/SGID, cron, systemd, sudoers, containers, kernel modules -- **Windows**: Registry, UAC, COM, DLL hijacking, named pipes, services, ACLs - -### AI Agent Compatibility - -This skill is designed to work across multiple AI coding agents: - -| Agent | Integration Method | -|-------|-------------------| -| **Trae / SOLO** | Global skill via `~/.trae/skills/csreview/SKILL.md` | -| **OpenCode** | Compatible via global agent instructions | -| **Qwen CLI** | Compatible via system prompt injection | -| **Codex** | Global skill via `~/.codex/skills/csreview/SKILL.md` or `~/.agents/skills/csreview/SKILL.md` | -| **Claude Code** | Global skill via `~/.claude/skills/csreview/SKILL.md` | -| **Antigravity** | Compatible via global agent configuration | -| **Qoder** | Compatible via agent configuration | -| **Cursor / Windsurf / Cline** | Compatible via global rules/instructions when supported | -| **GitHub Copilot CLI** | Compatible via global/custom instructions when supported | -| **Aider / Continue / DevChat** | Compatible via global agent conventions when supported | - -**Cross-Agent Behavior**: Regardless of which agent invokes this skill, the analysis depth, report format, and vulnerability detection remain consistent. The HTML report is always generated in the user's language; the MD report is always in English for agent consumption. - -## Analysis Phases +Key options (run `csreview --help` for the full list): -### Scatter-Gather Security Subagent Orchestration - -When the coding-agent runtime supports subagents and the workspace is large enough to justify the extra token/runtime cost, CSReview MAY ask the coding agent to use a scatter-gather workflow. This is an orchestration rule for agent reasoning, not a replacement for the deterministic npm engine. - -The dependency graph is: - -1. **Phase 0 + Phase 1 sequential gate**: first detect tools, run the engine-orchestrated SAST/SCA tools once, scan the local workspace, and build the shared project map (`techStack`, frameworks, package managers, BaaS files, database files, IaC files, routes, and generated tool JSON). -2. **Compatibility-gated fan-out**: spawn only the subagents that match the map. Examples: do not spawn a Delphi subagent without Pascal/Delphi files; do not spawn a Firebase subagent without Firebase rules/config; do not spawn a Go subagent without Go modules/files. -3. **Parallel validation**: compatible subagents validate candidate findings in their domain by reading the shared map, relevant local files, and cached tool output. They must not rerun heavy SAST/SCA tools across the whole tree. -4. **Gather barrier**: wait for all subagents to finish before ASVS/compliance correlation. -5. **Reduce/correlation**: one coordinator merges all partial findings, then runs `dedup -> ASVS -> compliance -> score -> report` in that order. -6. **Single writer**: Subagents MUST NOT write final reports. They may write only partial JSON to `csreview-reports/.partials/.json`. The coordinator is the only writer for `_security-report.html` and `_security-findings.md`, and partial files must use the canonical finding schema. - -Hard rules: - -- If subagents are unavailable, too expensive for the repository size, or not supported by the current agent, fallback to sequential analysis. -- Run SAST/SCA tools once in the gate stage; later subagents consume cached tool output instead of rerunning Semgrep, OSV-Scanner, Node package audit, Trivy, or similar whole-tree scans. -- Every subagent finding must use the canonical finding schema (`id`, `severity`, `category`, `name`, `description`, `file`, `line`, `vulnerableCode`, `cwe`, `owasp`, `fix`, `confidence`, `exploitation`, `references`, `source`). Use `source: "subagent:"`, for example `source: "subagent:auth"`, so the coordinator can correlate and deduplicate against `csreview-detector`, `semgrep`, `npm-audit`, and `osv-scanner`. -- Subagents do not write final reports and do not modify audited source code. -- The coordinator owns final deduplication. Matching `file:line:CWE` evidence from multiple sources can be promoted to `CONFIRMED`. - -#### Subagent Orchestration DoD - -1. **Single writer**: Subagents MUST NOT write final reports. Each subagent writes only partial findings JSON to its own scratch file, for example `csreview-reports/.partials/.json`. The coordinator is the only writer for `_security-report.html` and `_security-findings.md`. -2. **Canonical schema**: every subagent finding uses the engine finding object (`severity`, `category`, `file`, `line`, `cwe`, `confidence`, `fix`, and related fields) and sets `source: "subagent:"`. Without this, `deduplicateFindings` cannot correlate evidence or promote confidence to `CONFIRMED`. -3. **Tool runs once**: Semgrep, Node package audit, OSV-Scanner, Trivy, and similar whole-tree SAST/SCA tools run only during Phase 0/1. Their JSON output is cached, and subagents read the cache instead of re-executing tools on the tree. -4. **Compatibility-gated fan-out**: spawn a subagent only when Phase 1 detected its stack, framework, or ruleset. Do not spawn technology-specific subagents for absent ecosystems. -5. **Barrier before reduce**: ASVS mapping, compliance mapping, and score calculation run only after all partial findings have returned. The coordinator applies `dedup -> ASVS -> compliance -> score -> report`. - -**Final check**: CSReview produces one pair of final reports, the final count matches the sum of partial findings after deduplication, and no tool appears executed more than once in the log. - -**Engine enforcement**: when `csreview-reports/.partials/` exists, the npm engine reads canonical partial JSON, merges valid `source: "subagent:"` findings into the final finding set, exposes `partialReconciliation`, and provides `reconcilePartials(outputDir, finalFindings, { strict: true })` for coordinators that need the run to fail when the DoD does not reconcile. - -#### Non-negotiable rules - -1. **Single writer**: subagents write partial JSON only; the coordinator writes final reports. -2. **Canonical schema**: subagent findings must use the engine finding object and `source: "subagent:"`. -3. **Tool runs once**: whole-tree SAST/SCA tools run in Phase 0/1 only; subagents read cached JSON. - -### Phase 0: Security Tool Detection & Integration - -**This is the FIRST step of every analysis.** CSReview MUST detect which security tools are available on the user's operating system and use them for real file-by-file scanning. When real tools are not available, CSReview falls back to AI-based analysis (which is less thorough). - -#### 0.0 Analysis Modes - -CSReview operates in three modes. These mode names are based on the deterministic npm engine's orchestrated tools, not on every agent-recommended tool listed in this skill. - -**Mode A: Self-Hosted (RECOMMENDED)** -- All relevant engine-orchestrated tools are available locally: Semgrep, OSV-Scanner, and the Node package audit selected by lockfile (`pnpm audit` for `pnpm-lock.yaml`, `npm audit` for npm lockfiles). -- CSReview detects, invokes, parses, deduplicates, and scores these deterministic outputs. -- Findings from parsed tools are reproducible and can become `TOOL-ONLY` or `CONFIRMED` when matching CSReview detector evidence. -- Agent-recommended stack-native tools may still be listed as missing or supplemental; they do not change the engine mode unless their outputs are parsed by the npm engine. -- **This is the highest-confidence CSReview engine mode for local workspace analysis.** - -**Mode B: Agent-Only (FALLBACK)** -- No engine-orchestrated tool is available. -- CSReview relies on local scanner metadata plus regex/static heuristics and any careful agent reading of local files. -- **WARNING**: This mode has lower precision and recall. Line-oriented regex checks can miss multiline issues and may report false positives. -- Always clearly mark the run lower confidence and recommend installing Semgrep and OSV-Scanner before relying on the result. - -**Mode C: Hybrid (PARTIAL)** -- Some, but not all, relevant engine-orchestrated tools are available. -- CSReview runs available parsed tools and supplements them with detector heuristics and agent review. -- Tool findings are marked `TOOL-ONLY`; detector+tool agreement is deduplicated and promoted to `CONFIRMED`. -- Missing relevant tools must be disclosed in the report. - -**The agent MUST inform the user which mode is active and what the implications are.** - -#### 0.1 Tool Detection Protocol +| Option | Purpose | +| --- | --- | +| `--agent-name ` | Prefix report files with the coding agent name (or set `CSREVIEW_AGENT_NAME`) | +| `--output, -o ` | Output directory (default `/csreview-reports/`) | +| `--fail-on ` | CI gate: exit 1 when findings at or above `critical\|high\|medium\|low` remain | +| `--baseline ` / `--update-baseline` | Suppress known findings so CI fails only on NEW ones | +| `--provision-tools` | Opt-in: run Gitleaks/Trivy/gosec/Bandit; missing ones are downloaded from OFFICIAL releases, SHA-256-verified, into gitignored `.csreview/bin/` | +| `--tool-timeout ` | Per-tool timeout in seconds (default 120); timeouts are reported as timeouts, not as missing tools | +| `--semgrep-config ` | Use local/explicit Semgrep rules instead of `auto` (offline-friendly; adds `--metrics=off`) | +| `--local-dast-url ` + `--confirm-local-dast` | Phase 9 local-only dynamic complement (see below) | +| `--strict-partials` | Fail when subagent partials do not reconcile | +| `--no-update-check` | Skip the read-only, fail-open self-update advisory | -At the start of every scan, run detection commands for each tool. Use `RunCommand` or equivalent: +A `.csreview-ignore` file at the project root (gitignore-style globs) suppresses findings for matching paths in the report only. Unknown CLI flags are hard errors by design — a mistyped option aborts instead of silently changing what is audited. -#### 0.1.1 Engine-Orchestrated Tools +### Engine-Orchestrated Tools -These are the tools the npm engine currently invokes and parses deterministically: +The engine invokes and parses these deterministically; their findings enter deduplication and scoring: | Tool | Engine behavior | |------|-----------------| -| Semgrep | Runs `semgrep --config auto --json --quiet ` and parses findings | -| Node package audit | Runs `pnpm audit --json` when `pnpm-lock.yaml` exists, otherwise `npm audit --json` for npm lockfiles, and parses dependency findings | -| OSV-Scanner | Runs `osv-scanner scan --format json ` and parses dependency findings | -| Local DAST | Optional post-remediation local-only complement via `--local-dast-url`, writing separate reports | - -#### 0.1.2 Agent-Recommended Stack-Native Tools - -The tools below are recommended for agent-assisted validation when relevant to the detected stack. They are not parsed by the npm engine unless explicitly listed under Engine-Orchestrated Tools, so their results must be reported as supplemental evidence rather than silently merged into engine counts. - -**Detection Commands:** -```bash -# Semgrep - Multi-language static analysis (MANDATORY baseline attempt) -semgrep --version -# Required scan when available: semgrep --config auto --json --quiet +| Semgrep | **Mandatory baseline attempt** on every run: `semgrep --config auto --json --quiet ` (or `--semgrep-config `). If unavailable or timed out, the run is marked lower confidence with install instructions (`pipx install semgrep`). | +| Node package audit | Selected by lockfile: `pnpm audit --json` for `pnpm-lock.yaml`, `npm audit --json` for npm lockfiles, `bun audit --json` for `bun.lock`/`bun.lockb` | +| OSV-Scanner | `osv-scanner scan --format json ` for multi-ecosystem dependency vulnerabilities | +| Gitleaks / Trivy / gosec / Bandit | Only with `--provision-tools` (Bandit only if already installed); results corroborate the detector | +| Built-in detector | Heuristic patterns for secrets (redacted in evidence), config/IaC/BaaS misconfigurations (scoped to config-kind files), and common vulnerability shapes | +| Local DAST | Optional Phase 9 complement via `--local-dast-url`, separate reports | -# OSV-Scanner - Multi-ecosystem dependency vulnerability scanning -osv-scanner --version -# If found: osv-scanner scan --format json +### Analysis Modes -# Bandit - Python security linter -bandit --version -# If found: bandit -r -f json -ll +The engine reports which mode ran; the agent MUST tell the user and what it implies: -# Trivy - Vulnerability scanner (dependencies, containers, IaC) -trivy --version -# If found: trivy fs --format json --output report.json +- **Mode A: Self-Hosted (RECOMMENDED)** — all relevant engine-orchestrated tools are available; parsed, reproducible findings; highest-confidence engine mode. +- **Mode B: Agent-Only (FALLBACK)** — no engine-orchestrated tool available; regex/static heuristics plus careful agent reading. Lower precision and recall; line-oriented checks miss multiline issues. Mark the run lower confidence and recommend installing Semgrep and OSV-Scanner. +- **Mode C: Hybrid (PARTIAL)** — some tools available; missing ones are disclosed in the report. -# CodeQL - GitHub's semantic code analysis (if qlpack available) -codeql version -# If found: codeql database create / analyze +### Agent-Recommended Stack-Native Tools -# ESLint with security plugins -npx eslint --version 2>/dev/null || eslint --version -# If found: npx eslint --ext .js,.ts,.jsx,.tsx --config .eslintrc.security.json +Tools below are recommended for agent-assisted validation when relevant to the detected stack. They are **not parsed by the npm engine**: report their results as supplemental evidence, never silently merged into engine counts. Run a tool only if already available, already configured in the workspace, or provisioned with explicit user opt-in; do not install missing tools into the analyzed project or globally. If a relevant tool is unavailable, record it in the report as a `missing recommended tool` with the install pointer (see `reference/tooling.md` for detection, invocation, and installation commands). -# Snyk - Dependency vulnerability scanning -snyk --version -# If found: snyk test --json > report.json +#### Stack-Native Tool Recommendation Matrix -# SonarQube Scanner -sonar-scanner --version 2>/dev/null -# If found: sonar-scanner -Dsonar.projectKey=... -Dsonar.sources=. - -# Safety - Python dependency vulnerability checker -safety --version -# If found: safety check --json - -# Gosec - Go security linter -gosec --version -# If found: gosec -fmt json -out report.json ./... - -# Grype - Vulnerability scanner for container images and filesystems -grype version -# If found: grype dir: -o json - -# Hadolint - Dockerfile security linter -hadolint --version -# If found: hadolint Dockerfile --format json - -# TFLint - Terraform linter -tflint --version -# If found: tflint --format json - -# Checkov - Infrastructure-as-code security -checkov --version -# If found: checkov -d -o json - -# Brakeman - Ruby on Rails security scanner -brakeman --version -# If found: brakeman --format json -o report.json +| Detected stack | Prefer read-only commands and scanners | +| --- | --- | +| JavaScript / TypeScript / React / Node | lockfile-selected package audit (engine), configured `eslint`, `eslint-plugin-security`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `typescript-eslint`, Semgrep | +| .NET / C# / ASP.NET | `dotnet format analyzers --verify-no-changes`, `dotnet list package --include-transitive --vulnerable --format json`, Roslyn analyzers, Semgrep, CodeQL when available | +| Kotlin / Android / JVM | `gradlew lint` or `./gradlew lint`, Android Lint, `detekt`, `ktlint`, Qodana, Gradle dependency checks, OSV-Scanner, Semgrep | +| Go | `go vet ./...`, `govulncheck ./...`, `gosec ./...`, `staticcheck ./...`, `golangci-lint run`, OSV-Scanner, Semgrep | +| Python | `pip-audit`, `bandit -r`, `ruff check`, `safety` when available, OSV-Scanner, Semgrep | +| Java / Spring / Maven / Gradle | Maven/Gradle dependency checks, SpotBugs/FindSecBugs when configured, Checkstyle/PMD when configured, Qodana, OSV-Scanner, Semgrep | +| Rust | `cargo audit`, `cargo deny check`, `cargo clippy --all-targets --all-features`, OSV-Scanner, Semgrep | +| PHP / Laravel / Symfony | `composer audit --format=json`, PHPStan/Psalm when configured, OSV-Scanner, Semgrep | +| Ruby / Rails | `bundle audit`, `brakeman`, RuboCop when configured, OSV-Scanner, Semgrep | +| Flutter / Dart | `dart analyze`, `flutter analyze`, `dart pub outdated --json`, OSV-Scanner, Semgrep | +| IaC / containers / CI | Checkov, Trivy, Hadolint, Dockerfile linting, GitHub Actions linting, Terraform validators, Semgrep | +| BaaS / database rules | Supabase CLI checks when configured, Firebase rules validation when configured, Appwrite/Convex/PocketBase config review, SQL linters when configured, Semgrep | -# RetireJS - JavaScript library vulnerability scanner -retire --version -# If found: retire --path --outputformat json +## External Research Protocol -# OWASP Dependency-Check -dependency-check.sh --version 2>/dev/null || dependency-check --version 2>/dev/null -# If found: dependency-check --project --scan --format JSON +Do not guess when framework behavior, configuration defaults, security controls, exploitability, dependency advisories, CVE details, or remediation guidance are uncertain. Consult primary or specialized sources before reporting a confident recommendation: -# pip-audit - Python dependency auditing -pip-audit --version -# If found: pip-audit --format json +- official framework documentation, release notes, migration guides, and security pages +- vendor security advisory pages for the affected product, cloud service, database, BaaS, or package manager +- OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, Snyk advisories, and other specialized application security portals +- official package, API, or SDK documentation for the exact version in use -# cargo-audit - Rust dependency auditing -cargo audit --version -# If found: cargo audit --json +Include source names and URLs in finding references. Prefer official documentation and vendor advisories over blog posts. If sources disagree or the version cannot be confirmed, mark the finding lower confidence and explain the uncertainty. -# npm audit (always available with npm) -npm --version -# If found: npm audit --json +## Execution Workflow -# pnpm audit (selected when pnpm-lock.yaml exists) -pnpm --version -# If found: pnpm audit --json +1. **Confirm global skill scope** (Core Rule 2) if the task involves installing or updating CSReview itself. +2. **Announce the scan** and run the engine: `csreview --agent-name ` (plus `--provision-tools` when the user opted in, `--baseline` when one exists). The engine performs tool detection, the tool runs, workspace discovery, heuristic detection, deduplication, scoring, and report generation. +3. **Report the mode** (Self-Hosted / Hybrid / Agent-Only) and which tools ran, were skipped, or timed out — exactly as the engine printed them. +4. **Contextual review pass**: read the Markdown report, then inspect the flagged files and their surroundings using the checklists in `reference/security-checklists.md` (injection, auth, data leakage, BaaS rules, platform-specific surfaces, database security, Firebase cost patterns). Validate or discount engine findings with file-level context; research anything uncertain (External Research Protocol). +5. **Supply-chain and compliance correlation** when the user asked for it: use `reference/compliance-frameworks.md` (SLSA Build L3 (v1.2) checklist, OWASP ASVS 5.0.0 areas, LGPD/GDPR/SOC2/HIPAA/CCPA-CPRA) — correlation and judgment, never fabricated percentages. +6. **Vibe Coding Heuristics**: the engine attaches a `vibeRisk` flag — a static boolean heuristic marking vulnerability patterns that commonly appear in rushed or AI-assisted code. It does not prove AI authorship and is a prioritization hint, nothing more. +7. **Deliver the reports** (Report Handoff Protocol below) and a verbal summary of CRITICAL/HIGH findings, tool-detected vs heuristic-only counts, and disclosed gaps. +8. **Offer next steps**: a prioritized remediation plan, or a coding-agent session to apply selected fixes with project-context validation, then a re-run (optionally `--update-baseline` after triage, `--fail-on high` in CI). +9. **Offer Phase 9** (optional local DAST) only after remediation work. -# yarn audit -yarn --version -# If found: yarn audit --json +The default report covers 8 sections: Reconnaissance, Ultra-Deep Security, Database Security, SLSA Build L3 (v1.2) Supply Chain, OWASP ASVS 5.0.0, Compliance mapping (LGPD/GDPR/SOC2/HIPAA/CCPA-CPRA — indicative correlation, not an audited compliance verification), Vibe Coding Protection, and Dual Report Generation. These are report sections, not separate executable engine phases. -# dotnet list package --vulnerable (always available with dotnet) -dotnet --version -# If found: dotnet list package --vulnerable --include-transitive -``` +## Report Handoff Protocol -#### 0.2 Tool Selection Matrix - -After detection, select tools based on detected project languages: - -| Language/Framework | Primary Tools | Secondary Tools | -|-------------------|---------------|-----------------| -| **JavaScript/TypeScript** | semgrep, eslint (security), npm audit or pnpm audit selected by lockfile, osv-scanner | snyk, retire | -| **Python** | bandit, safety, pip-audit, osv-scanner | semgrep, snyk | -| **Go** | gosec, govulncheck, trivy, osv-scanner | semgrep | -| **C# / .NET** | dotnet list package --vulnerable, osv-scanner | semgrep, snyk | -| **Java** | semgrep, snyk, OWASP dep-check, osv-scanner | trivy | -| **Ruby** | brakeman, bundler-audit | semgrep | -| **Rust** | cargo audit, osv-scanner | semgrep, trivy | -| **PHP** | semgrep, snyk | psalm (security) | -| **Kotlin/Swift** | semgrep, snyk | trivy | -| **Docker** | hadolint, trivy, grype | checkov | -| **Terraform/IaC** | checkov, tflint, trivy | semgrep | -| **Delphi/Lazarus** | AI-based analysis only | semgrep (if available) | -| **Multi-language** | semgrep, osv-scanner, trivy | snyk, grype | - -#### 0.3 Execution Strategy - -**When real tools ARE available:** -1. Run all applicable tools in parallel (use `RunCommand` with `blocking: false` for each) -2. Collect JSON output from each tool -3. Parse and normalize findings into unified format -4. Merge with AI-based analysis (Phase 1-7) for comprehensive coverage -5. Deduplicate findings (same file+line+type = same issue) -6. Prioritize: tool findings take precedence over AI-only findings - -**When real tools are NOT available:** -1. Inform the user: "No security scanning tools detected. Using AI-based analysis only. For better accuracy, install: [recommended tools for their stack]" -2. Run AI-based analysis (Phase 1-7) with enhanced depth -3. Add a disclaimer to reports: "This report was generated using AI-based analysis only. For production security audits, install and run: semgrep, [language-specific tool]" -4. Still generate both HTML and MD reports, but mark findings with confidence level - -**Confidence Levels:** -| Level | Source | Description | -|-------|--------|-------------| -| **CONFIRMED** | Real tool + AI agree | Highest confidence - both tool and AI identified the issue | -| **TOOL-ONLY** | Real tool only | Issue found by tool but not confirmed by AI review | -| **AI-ONLY** | AI analysis only | Issue found by AI but not detected by tools | -| **AI-ESTIMATED** | No tools available | AI-based analysis only, lower confidence | - -#### 0.4 Tool Output Normalization - -Each tool's output must be normalized into this unified format: - -```json -{ - "source": "semgrep|bandit|trivy|snyk|eslint|codeql|gosec|...", - "id": "unique-finding-id", - "severity": "CRITICAL|HIGH|MEDIUM|LOW|INFO", - "category": "injection|xss|auth|config|dependency|...", - "file": "relative/path/to/file", - "line": 42, - "column": 10, - "title": "Short description", - "description": "Detailed description", - "cwe": "CWE-89", - "confidence": "CONFIRMED|TOOL-ONLY|AI-ONLY|AI-ESTIMATED", - "fix": "Suggested fix or remediation", - "references": ["url1", "url2"], - "tool_metadata": { - "rule_id": "semgrep-rule-id", - "owasp_category": "A03:2021", - "cve": "CVE-2024-XXXX" - } -} -``` +After every CSReview run, the agent MUST present two explicit paths: -#### 0.5 Per-Tool Invocation Details +- **Agent name prefix**: report filenames MUST begin with the coding agent name in lowercase, for example `codex_security-report.html` and `codex_security-findings.md`. Other agents replace `codex` with their own name, such as `claude_security-report.html`. Pass `--agent-name ` or set `CSREVIEW_AGENT_NAME=`. +- **MUST NOT generate generic report names**: `security-report.html`, `security-findings.md`, `csreview-report.html`, and similar agent-less names are invalid handoff names because they hide which agent produced the analysis. +- **HTML report path**: the absolute path to `csreview-reports/codex_security-report.html` (or configured output). Tell the user this is the file to open in a browser for human reading; if a browser-opening tool is available and the user asked, open it. +- **Markdown report path**: the absolute path to `csreview-reports/codex_security-findings.md`. The coding agent must analyze this file before planning any remediation — never infer findings from the verbal summary alone. For remediation work, read the Markdown report first, then inspect the referenced source files, framework documentation, schemas, tests, and security advisories before proposing changes. +- **SARIF path**: `csreview-reports/codex_security.sarif` for CI / GitHub code scanning ingestion (no raw vulnerable code embedded). -**Semgrep (highest priority - multi-language):** -```bash -# Auto-detect rules from registry -semgrep --config auto --json --quiet --no-git-ignore +## Finding Semantics -# With specific rulesets -semgrep --config p/security-audit --config p/secrets --config p/owasp-top-ten --json -``` +Confidence labels (engine-emitted): `CONFIRMED` (corroborated by independent sources at the same file:line:CWE), `TOOL-ONLY` (one external tool), `HIGH`/`MEDIUM`/`LOW` (heuristic detector confidence; non-source paths such as tests/fixtures are downgraded to LOW). Exploitation text in findings is always a **Potential Exploitation Path (theoretical, unverified)** — a hypothesis derived from static analysis, not a validated or executed exploit. Full report anatomy and the canonical finding schema: `reference/reports.md`. -**Bandit (Python-specific):** -```bash -bandit -r -f json -ll -i --skip B101 -# -ll = medium and high severity only -# --skip B101 = skip assert warnings (too noisy) -``` +Severity classification: -**Trivy (comprehensive scanner):** -```bash -# Filesystem scan (dependencies + misconfigs) -trivy fs --format json --scanners vuln,misconfig,secret +| Severity | Criteria | Response | +|----------|----------|----------| +| **CRITICAL** | Direct data breach, RCE, auth bypass, exposed PII/secrets | Immediate fix | +| **HIGH** | Significant vulnerability, exploitable with effort | 24-48h | +| **MEDIUM** | Moderate risk, requires specific conditions | Within a week | +| **LOW** | Minor issue, defense-in-depth | Next sprint | +| **INFO** | Best-practice recommendation | Consider | -# With severity filter -trivy fs --severity HIGH,CRITICAL --format json -``` +## Scatter-Gather Security Subagent Orchestration -**OSV-Scanner (multi-ecosystem dependency SCA):** -```bash -osv-scanner scan --format json -``` -- Parse JSON `results[].packages[].vulnerabilities[]` -- Map findings to OWASP A06: Vulnerable and Outdated Components -- Do not run `osv-scanner fix` or guided remediation during CSReview +When the agent runtime supports subagents and the workspace is large enough to justify the cost, CSReview MAY use a scatter-gather workflow; otherwise fallback to sequential analysis. The flow is: **Phase 0 + Phase 1 sequential gate** (engine run + shared project map) → **compatibility-gated fan-out** (spawn only subagents matching detected stacks) → parallel validation against cached tool output → gather barrier → reduce (`dedup -> ASVS -> compliance -> score -> report`). -**Node package audit (Node.js dependencies):** -```bash -cd && npm audit --json # npm lockfiles -cd && pnpm audit --json # pnpm-lock.yaml -``` -- Parse npm `vulnerabilities` and pnpm `advisories` -- Do not run package-manager fix/update commands during CSReview +### Subagent Orchestration DoD -**Snyk (if authenticated):** -```bash -snyk test --json --severity-threshold=medium -``` +1. **Single writer**: Subagents MUST NOT write final reports. Each writes only partial findings JSON to `csreview-reports/.partials/.json`; the coordinator is the only writer of the final reports. +2. **Canonical finding schema**: every partial finding uses the engine finding object and sets `source: "subagent:"` — without it the engine cannot correlate evidence or promote to `CONFIRMED`. +3. **Run SAST/SCA tools once**: whole-tree tools (Semgrep, package audit, OSV-Scanner, Trivy) run only in the gate; subagents read cached tool output instead of re-executing them. -**Gosec (Go-specific):** -```bash -gosec -fmt json -out /tmp/gosec-report.json -severity medium ./... -``` +**Final check**: CSReview produces one pair of final reports, the final count matches the sum of partial findings after deduplication, and no tool appears executed more than once in the log. The engine enforces this via `partialReconciliation` (`--strict-partials` to fail hard). -**dotnet (C#/.NET dependencies):** -```bash -dotnet list package --vulnerable --include-transitive -``` +### Non-negotiable rules -**cargo audit (Rust):** -```bash -cargo audit --json -``` +1. Single writer — partial JSON only; the engine/coordinator writes reports. +2. Canonical schema with `source: "subagent:"`. +3. Whole-tree tools run once, in the gate. -**pip-audit (Python dependencies):** -```bash -pip-audit --format json --desc -``` +Full protocol and partial-file contract: `reference/subagents.md`. -**Checkov (IaC security):** -```bash -checkov -d -o json --quiet --compact -``` +## Phase 9: Optional Local DAST Complementary Report -**Hadolint (Dockerfile):** -```bash -hadolint /Dockerfile --format json -``` +Available only after the user or coding agent has implemented and validated remediations from the static report. It MUST NOT start automatically, and it is a conservative local HTTP probe (reachability, security headers, CORS), NOT a full penetration test. -#### 0.6 Installation Recommendations +The required user-facing prompt is: "Static remediation is complete. You can optionally run CSReview Phase 9 Local DAST in a local test environment only. Never use this against production. If the test uses a database copy, make sure the copy was made deliberately, stored in a secure local place, and sanitized or minimized where needed. This resource is for White Hat Hacker-style analysis and remediation of security flaws; it sends real HTTP requests only to localhost/127.0.0.1 and writes a complementary report. Do you want me to run it? (yes/no)" -When tools are missing, provide platform-specific installation instructions: +Phase 9 may proceed only with explicit user confirmation, only for a local test environment, never production, and only against `http(s)://localhost:`, `http(s)://127.0.0.1:`, or `http(s)://[::1]:`. The engine enforces the hard guards: redirects are never followed — if a response points to an external host, abort Phase 9 immediately; reports are written only inside `csreview-reports/` (`csreview-reports/_local-dast-report.html`, `_local-dast-findings.md`, plus run-ID history copies and the read-only `_db-dump-guide.html`). ```bash -# Semgrep (all platforms) -pipx install semgrep -# Alternative: uv tool install semgrep - -# OSV-Scanner -# Windows: winget install Google.OSVScanner -# macOS/Linux: brew install osv-scanner -# Go: go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest - -# Bandit (Python) -pip install bandit - -# Trivy (all platforms) -# Windows: choco install trivy OR scoop install trivy -# macOS: brew install trivy -# Linux: sudo apt-get install trivy OR curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh - -# Snyk -npm install -g snyk - -# Gosec (Go) -go install github.com/securego/gosec/v2/cmd/gosec@latest - -# pip-audit -pip install pip-audit - -# cargo audit -cargo install cargo-audit - -# Checkov -pip install checkov - -# Hadolint -# Windows: choco install hadolint -# macOS: brew install hadolint -# Linux: docker pull hadolint/hadolint - -# ESLint Security Plugin -npm install --save-dev eslint-plugin-security eslint-plugin-no-unsanitized +csreview . --local-dast-url http://localhost:3000 --confirm-local-dast --agent-name codex ``` -### Phase 1: Reconnaissance & Mapping - -1. **Project Structure Scan** - - Identify all languages, frameworks, and dependencies - - Map entry points, API routes, and data flow paths - - Locate configuration files (.env, config.*, database.yml, etc.) - -2. **Secret Detection** - - Hardcoded API keys, tokens, passwords - - Connection strings with credentials - - Private keys, certificates, secrets in code - - Environment files committed to version control - -3. **External Service Mapping** - - Supabase: tables, RLS policies, edge functions, storage rules - - Firebase: database rules, storage rules, auth config - - Appwrite: collections, permissions, functions - - AWS/GCP/Azure: IAM roles, S3 buckets, exposed endpoints - -### Phase 2: Ultra-Deep Security Analysis - -#### 2.1 Injection Vulnerabilities -- **SQL Injection**: Raw queries, string concatenation, ORM misuse -- **NoSQL Injection**: MongoDB query injection, Redis command injection -- **Command Injection**: exec(), system(), subprocess calls with user input -- **LDAP Injection**: Directory service query manipulation -- **XPath Injection**: XML query manipulation -- **Template Injection**: SSTI in Jinja2, Twig, EJS, etc. - -#### 2.2 Authentication & Authorization -- **JWT Flaws**: Missing validation, weak secrets, algorithm confusion -- **Session Management**: Insecure cookies, missing HttpOnly/Secure flags -- **RLS Policies**: Missing or bypassable Row Level Security (Supabase) -- **Role-Based Access**: Privilege escalation, missing authorization checks -- **IDOR**: Insecure Direct Object References exposing other users' data -- **OAuth/OpenID**: Misconfigured flows, token leakage, redirect URI flaws - -#### 2.3 Data Leakage -- **Log Exposure**: Sensitive data in console.log, logger, error messages -- **Stack Traces**: Full error details exposed to users -- **PII Exposure**: Personal data in API responses without filtering -- **Debug Mode**: Debug endpoints or panels enabled in production -- **Response Headers**: Server version, framework info leakage -- **Cache Exposure**: Sensitive data cached in browser or CDN - -#### 2.4 Cross-Site Vulnerabilities -- **XSS**: Reflected, stored, DOM-based (dangerouslySetInnerHTML, v-html) -- **CSRF**: Missing tokens, SameSite cookie misconfiguration -- **CORS**: Overly permissive origins, wildcard Access-Control-Allow-Origin -- **Clickjacking**: Missing X-Frame-Options or CSP frame-ancestors - -#### 2.5 Insecure Configurations -- **Security Headers**: Missing CSP, HSTS, X-Content-Type-Options -- **TLS/SSL**: Weak ciphers, missing certificate pinning, HTTP fallback -- **File Uploads**: Missing validation, executable file upload, path traversal -- **Rate Limiting**: Missing brute force protection, API abuse vectors -- **Error Handling**: Verbose errors, information disclosure - -#### 2.6 Dependency Vulnerabilities -- **Outdated Packages**: Known CVEs in dependencies -- **Supply Chain**: Suspicious packages, typosquatting, compromised deps -- **License Compliance**: Restrictive licenses in production - -#### 2.7 Cloud & Backend Security -- **Supabase**: - - Missing RLS policies on sensitive tables - - Overly permissive policies (allow all authenticated) - - Exposed service role key in client code - - Storage bucket public access misconfiguration - - Edge function authentication bypass -- **Firebase**: - - Database rules allowing read/write to all users - - Storage rules without authentication checks - - Exposed API keys with excessive permissions - - Missing App Check enforcement -- **Appwrite**: - - Collection permissions too permissive - - Missing attribute validation - - Function execution without auth checks - -#### 2.8 Platform-Specific Vulnerabilities - -**macOS:** -- App Sandbox escape vectors -- Keychain insecure access patterns -- TCC (Transparency, Consent, Control) permission abuse -- Plist misconfigurations exposing sensitive data -- XPC service vulnerabilities -- Gatekeeper bypass vectors -- Insecure file permissions (world-readable/writable) - -**iOS:** -- Insecure URL scheme handling -- Keychain data exposure -- Missing jailbreak detection -- TLS certificate validation bypass -- UserDefaults storing sensitive data -- Biometric authentication flaws -- App Transport Security (ATS) disabled -- Screenshot/cache exposure of sensitive screens -- Insecure WKWebView configurations - -**Linux:** -- SUID/SGID binary vulnerabilities -- Cron job injection or race conditions -- Insecure systemd service configurations -- File permission escalation vectors -- Sudoers misconfigurations -- Exposed Unix sockets -- Kernel module vulnerabilities -- Container escape vectors (Docker, LXC) -- Insecure mount options - -**Windows:** -- Registry key exposure of sensitive data -- UAC bypass vectors -- Insecure COM object configurations -- DLL hijacking vulnerabilities -- Named pipe access control flaws -- Service account privilege escalation -- PowerShell execution policy bypass -- Insecure ACLs on files/directories -- Token impersonation flaws - -#### 2.9 Cross-Platform System Vulnerabilities -- **Path Traversal**: File operations with unsanitized paths -- **Symlink Attacks**: Following malicious symlinks -- **Environment Variable Injection**: Untrusted env var manipulation -- **Insecure Temp Files**: Predictable temp file names -- **Race Conditions**: TOCTOU in file/resource access -- **Memory Corruption**: Buffer overflow, use-after-free in native code -- **IPC Insecurity**: Unprotected inter-process communication -- **Credential Storage**: Plaintext passwords, tokens, keys - -#### 2.10 .NET / dotnet Security - -**ASP.NET Core / Blazor:** -- Missing `[Authorize]` attributes on controllers/pages -- CORS policy set to `AllowAnyOrigin` in production -- Missing anti-forgery tokens (`[ValidateAntiForgeryToken]`) -- Insecure cookie configuration (missing HttpOnly, Secure, SameSite) -- Sensitive data in `appsettings.json` without user secrets or key vault -- Missing rate limiting middleware -- Debug mode enabled in production (`ASPNETCORE_ENVIRONMENT=Development`) -- Missing HTTPS redirection and HSTS -- Insecure Data Protection API key storage -- Missing input validation with `[ValidateInput]` or FluentValidation - -**Entity Framework / EF Core:** -- Raw SQL queries with string interpolation (`FromSqlRaw` with unsanitized input) -- Missing parameterization in LINQ-to-SQL dynamic queries -- Lazy loading without `ProxyCreationEnabled` control (N+1 queries) -- Excessive `Include()` chains loading unnecessary related data -- Missing migration rollback scripts -- Connection strings with credentials in plain text -- Missing database connection encryption - -**NuGet / Package Security:** -- Packages from untrusted sources -- Missing `nuget.config` source restrictions -- Packages with known vulnerabilities (check against CVE database) -- Transitive dependency vulnerabilities -- Missing lock files (`packages.lock.json`) - -**.NET Binary Security:** -- Missing strong naming / signing of assemblies -- `AllowPartiallyTrustedCallers` attribute misuse -- Missing `[SecurityCritical]` / `[SecuritySafeCritical]` boundaries -- Reflection-based type loading from untrusted sources -- BinaryFormatter / SoapFormatter deserialization (known insecure) -- Missing `SecureString` usage for sensitive data in memory - -#### 2.11 Delphi / Lazarus Security - -**Delphi (VCL / FireMonkey):** -- Hardcoded database credentials in `.dpr` or `.pas` files -- Missing encryption for stored connection strings -- BDE (Borland Database Engine) insecure configurations -- dbExpress / FireDAC connection strings with plaintext passwords -- Insecure file operations (no path validation on user input) -- Missing input validation on TForm controls -- COM automation with late binding (variant-based) without safety checks -- Unsafe pointer operations and untyped `var` parameters -- Missing bounds checking on dynamic arrays and strings (`{$RANGECHECKS ON}`) -- Insecure registry operations (direct Windows Registry access without validation) -- Missing overflow checking (`{$OVERFLOWCHECKS ON}`) - -**Lazarus / Free Pascal:** -- Hardcoded credentials in `.lpr` or `.pas` source files -- SQLite databases without encryption (SQLite3 without SEE or sqlcipher) -- Missing parameterized queries in SQLdb components -- Insecure INI file configurations with sensitive data -- Missing TLS for network communications (Indy / Synapse without SSL) -- Form data stored without encryption -- Insecure file permissions on Linux deployments -- Missing `{$MODESWITCH ANSISTRINGS}` causing string handling issues -- Buffer overflows in `Move`, `FillChar`, `GetMem` operations -- Missing exception handling around database operations - -**Database Connectivity (Delphi/Lazarus):** -- Firebird/InterBase connection strings with embedded passwords -- Missing SSL/TLS for database connections -- Unencrypted `.fdb` / `.gdb` database files -- IBX / FIBPlus components with default credentials -- Missing `EXECUTE STATEMENT` parameterization in Firebird PSQL -- zeoslib connection pooling misconfigurations - -#### 2.12 Go Security - -**Web Frameworks (Gin, Echo, Fiber):** -- Missing input validation middleware -- SQL injection via `fmt.Sprintf` in queries instead of parameterized statements -- Missing CSRF protection -- Unbounded file uploads without size/type validation -- Missing rate limiting -- CORS middleware with `AllowAllOrigins: true` -- Missing request body size limits -- Error messages leaking internal state - -**Go-Specific Vulnerabilities:** -- `exec.Command` with unsanitized user input -- `os.ReadFile` / `ioutil.ReadFile` with user-controlled paths (path traversal) -- `template.HTML` bypassing auto-escaping -- `unsafe.Pointer` usage and CGo boundary vulnerabilities -- Missing bounds checking in slice operations -- Goroutine leaks (missing context cancellation) -- Race conditions from shared mutable state without `sync.Mutex` -- `json.Unmarshal` into `interface{}` without schema validation -- Missing `context.WithTimeout` for external service calls -- Hardcoded credentials in source code - -**Go Modules:** -- `go.sum` integrity verification failures -- Replaced modules (`replace` directive) pointing to untrusted sources -- Missing `go.sum` file in repository -- Modules with known vulnerabilities (`govulncheck`) -- Private module proxy misconfigurations - -#### 2.13 Installer & DLL Security - -**DLL Security:** -- DLL hijacking: application loads DLL from current directory before system paths -- DLL side-loading: legitimate app loading malicious DLL from same directory -- Missing Address Space Layout Randomization (ASLR) flag -- Missing Data Execution Prevention (DEP) / NX bit flag -- Unsigned DLLs in production deployments -- Export table exposing sensitive functions -- DLL injection vectors (missing process integrity levels) -- Insecure DLL search order (current directory before System32) - -**Installer Security (Inno Setup / NSIS / WiX / MSI):** -- Custom actions running with elevated privileges -- Missing digital signature on installer executable -- Insecure file permissions set during installation -- Hardcoded credentials in installer scripts -- Missing uninstall cleanup (leftover sensitive files/registry keys) -- Insecure temporary directory usage during installation -- Missing integrity checks on extracted files -- Pre-install validation missing (disk space, prerequisites) -- Insecure custom protocol handlers registered during install -- MSI custom actions with `Impersonate="no"` (running as SYSTEM) - -**Binary & Executable Security:** -- Missing Authenticode / code signing -- Missing checksum verification for downloaded updates -- Insecure auto-update mechanism (HTTP instead of HTTPS, no signature verification) -- Debug symbols included in release builds -- PDB files deployed to production -- Sensitive strings embedded in binary (use string search analysis) -- Missing compiler security flags (`/GS` buffer security check, `/DYNAMICBASE`, `/NXCOMPAT`) -- Insecure compiler optimizations that remove security checks - -#### 2.14 Logic & Business Flaws -- **Race Conditions**: Concurrent request exploitation -- **TOCTOU**: Time-of-check to time-of-use vulnerabilities -- **Business Logic Bypass**: Skipping payment, validation bypass -- **Mass Assignment**: Unfiltered model updates from user input -- **Insecure Deserialization**: Pickle, YAML, JSON parsing flaws - -### Phase 3: Database Security Analysis - -Deep analysis of database structures, configurations, and access patterns across SQL, NoSQL, and BaaS platforms. - -#### 3.1 SQL Database Security - -**Structure Analysis:** -- Schema design flaws enabling data leakage -- Missing foreign key constraints allowing orphaned/inconsistent data -- Overly permissive column types (VARCHAR(MAX) for sensitive fields) -- Missing audit columns (created_at, updated_at, created_by) -- Lack of soft delete patterns for compliance data - -**Query Security:** -- Dynamic SQL construction with string concatenation -- Stored procedures with SQL injection vectors -- Missing parameterized queries in ORM raw query usage -- Overly broad SELECT statements (SELECT * instead of column selection) -- Missing LIMIT/OFFSET on unbounded queries enabling data exfiltration -- Cursor-based attacks on large result sets - -**Access Control:** -- Database users with excessive privileges (DBA for app connections) -- Missing row-level security policies -- Default database credentials unchanged -- Database accessible from public networks -- Missing connection encryption (TLS/SSL) -- Connection string hardcoded or in version control - -**Platform-Specific SQL Checks:** -- **PostgreSQL**: RLS policies, pg_hba.conf, superuser roles, extension security (pg_crypto vs plaintext), search_path injection -- **MySQL/MariaDB**: GRANT privileges, LOAD DATA INFILE, secure-file-priv, binary log exposure -- **SQL Server**: xp_cmdshell enabled, TRUSTWORTHY database property, dynamic SQL in stored procedures -- **Firebird**: SYSDBA default password, UDF library security, role-based access -- **SQLite**: File permissions, encryption at rest (SEE/sqlcipher), journal mode security -- **Oracle**: TNS listener security, default accounts, privilege escalation via PL/SQL - -#### 3.2 NoSQL Database Security - -**MongoDB:** -- Authentication disabled (default in older versions) -- Bind address set to 0.0.0.0 (public access) -- Missing field-level encryption for PII -- NoSQL injection via operator injection ($gt, $ne, $regex) -- Aggregation pipeline injection -- Missing schema validation allowing arbitrary document structure -- GridFS exposed without access control -- Missing audit logging - -**Redis:** -- No authentication (requirepass not set) -- BIND set to 0.0.0.0 -- Dangerous commands enabled (FLUSHALL, CONFIG, DEBUG, EVAL) -- Lua script injection -- Missing rename-command for sensitive operations -- Unencrypted connections (no TLS) -- Keyspace exposure via INFO/KEYS commands - -**CouchDB:** -- Admin party mode (no authentication) -- Missing validate_doc_update functions -- Overly permissive _security objects -- CORS misconfiguration -- Futon admin panel exposed - -**DynamoDB:** -- Overly permissive IAM policies -- Missing encryption at rest -- No point-in-time recovery enabled -- Missing VPC endpoint for private access -- Scan operations without pagination limits - -**Cassandra:** -- Authenticator set to AllowAllAuthenticator -- Missing encryption (server-to-server, client-to-server) -- Overly broad permissions grants -- Missing audit logging - -#### 3.3 BaaS Platform Security - -**Supabase:** -- Missing RLS policies on tables with sensitive data -- RLS policies with `true` condition (allow all) -- Service role key exposed in client-side code -- Edge functions without authentication -- Storage buckets with public access for sensitive files -- Realtime subscriptions without authorization checks -- Missing database webhooks validation -- Exposed PostgREST configuration -- Missing rate limiting on API endpoints - -**Firebase/Firestore:** -- Database rules allowing unauthenticated read/write -- Firestore rules without proper `request.auth` checks -- Storage rules without file type/size validation -- Missing App Check enforcement -- API key exposed with overly permissive restrictions -- Cloud Functions without authentication -- Missing security rules for subcollections -- Realtime Database rules too permissive - -**Firebase Cost & Performance Security:** - -*Rule-Based Cost Detection:* -- Firestore rules with `allow read, write: if true;` (unlimited reads/writes = cost explosion) -- Firestore rules with `allow read: if request.auth != null;` (any authenticated user can read ALL documents) -- Realtime Database rules with `.read: true` or `.write: true` at root level -- Storage rules allowing unlimited file uploads without size/type restrictions -- Missing `request.resource.size` limits in Firestore create/update rules -- Rules that allow listing entire collections without filters (`allow list` without `request.query.limit`) - -*Query Cost Analysis:* -- `getDocs(collection(db, "collection"))` without pagination (reads entire collection) -- `getDocs(query(collection(db, "collection")))` without `.limit()` clause -- Missing cursor-based pagination (`startAfter`, `startAt`, `endBefore`, `endAt`) -- Realtime Database `ref.once('value')` on root or large nodes -- Excessive snapshot listeners (`onSnapshot`) without proper unsubscribe -- Multiple concurrent `getDoc()` calls instead of batched reads or `getAll()` -- `getDocs()` inside loops (N+1 query pattern in Firestore) -- Missing field selection (reading entire documents when only few fields needed) -- Collection group queries without security rules covering all subcollections - -*Cloud Functions Cost Triggers:* -- Firestore `onWrite`/`onCreate` triggers on high-write collections (each trigger = function invocation cost) -- Storage `onArchive`/`onDelete` triggers without event filtering -- HTTP functions without rate limiting (vulnerable to DDoS = cost spike) -- Scheduled functions running too frequently without purpose -- Functions with excessive memory allocation (always using 2GB when 256MB suffices) -- Missing `minInstances: 0` (keeping instances alive when not needed) -- `onRequest` functions without timeout configuration -- Functions that perform unnecessary reads before writes -- Recursive trigger patterns (function writes to same collection that triggers it) - -*Realtime Database Cost Patterns:* -- Deep listeners on root node (`ref.on('value')` at `/`) -- Missing `.indexOn` rules causing full database scans for queries -- Large JSON structures stored as single nodes instead of distributed paths -- Missing disconnect handlers leaving stale data -- Excessive `ref.set()` calls instead of batched `ref.update()` -- Not using `ref.once()` when real-time updates aren't needed - -*Storage Cost Patterns:* -- Missing file compression before upload (uploading uncompressed images/videos) -- No upload size limits enforced client-side AND server-side -- Missing file cleanup on account/document deletion -- Using `uploadBytes` instead of `uploadBytesResumable` for large files (memory spikes) -- Missing Firebase App Check for Storage (unauthorized uploads = cost) -- Not using CDN caching headers for public files (repeated downloads = cost) -- Missing lifecycle rules for old/deleted files - -*Firestore Index Cost:* -- Missing composite indexes causing query failures or full scans -- Over-indexing (indexes on fields rarely queried = unnecessary write cost) -- Single-field index exemptions not configured for high-write fields -- Array-contains queries on large arrays (index size bloat) - -*Connection & Instance Cost:* -- Excessive simultaneous Realtime Database connections (free tier: 100, paid: billed per connection) -- Firestore listeners not properly cleaned up on component unmount -- Missing offline persistence configuration causing reconnection storms -- Multiple Firebase app instances initialized unnecessarily -- Not using `firebase-admin` batch operations for bulk writes (individual writes = more cost) -- Missing connection pooling for server-side Firebase Admin SDK - -*Cost Estimation Patterns:* -- Estimate monthly read/write/delete costs based on code patterns -- Identify potential infinite loops in Firestore triggers -- Detect patterns where a single user action triggers N database operations -- Flag unbounded queries that could read millions of documents -- Calculate projected storage growth without cleanup policies -- Identify missing budget alerts and spending limits configuration - -**Appwrite:** -- Collection permissions set to `any` (public) -- Missing attribute-level validation -- Function execution without authentication -- Storage bucket permissions too broad -- Missing webhook signature validation -- API key scope too permissive - -**Neon (Serverless Postgres):** -- Connection string with credentials in code -- Missing SSL/TLS enforcement -- Branch-based access not restricted -- Pooler connection security -- Missing RLS policies (same as PostgreSQL) -- API key exposure - -**PocketBase:** -- Default admin credentials unchanged -- Collection rules too permissive -- Missing field encryption for sensitive data -- File upload rules without validation -- API rate limiting not configured - -**Convex:** -- Missing authentication in functions -- Overly broad document access rules -- Missing validation on mutations -- Sensitive data in function arguments (logged) -- Missing row-level security patterns - -### Phase 4: SLSA Build L3 (v1.2) Supply Chain Security - -Assess supply chain integrity against SLSA (Supply-chain Levels for Software Artifacts) framework. - -#### 4.1 Source Integrity -- **Version Control**: Signed commits verification, branch protection rules -- **Code Review**: Required reviews for merges, CODEOWNERS file present -- **Access Control**: Repository permissions audit, 2FA enforcement -- **Provenance**: Source location verifiable, build instructions documented - -#### 4.2 Build Integrity -- **Build Pipeline**: Automated CI/CD, reproducible builds, hermetic builds -- **Build Service**: Hosted build service (not developer machine), isolated environments -- **Build Provenance**: Signed build attestations, SLSA provenance generation -- **Artifact Signing**: Artifacts signed with Sigstore/cosign/GPG -- **Container Security**: Base image verification, no root user, minimal layers - -#### 4.3 Dependency Security -- **Lock Files**: package-lock.json, yarn.lock, Pipfile.lock, Cargo.lock present and committed -- **Pinning**: Dependencies pinned to exact versions (not ranges) -- **Verification**: Dependency integrity hashes verified -- **SBOM**: Software Bill of Materials generated and maintained -- **Vulnerability Scanning**: Automated dependency vulnerability scanning configured -- **Typosquatting**: Check for suspicious package names -- **License Audit**: All dependency licenses compatible with project license - -#### 4.4 Deployment Security -- **Environment Separation**: Clear separation between dev/staging/production -- **Secret Management**: Secrets in vault/manager, not in code or env files -- **Access Deployment**: Deployment access restricted and audited -- **Rollback Capability**: Ability to rollback deployments securely -- **Infrastructure as Code**: IaC templates audited for misconfigurations - -### Phase 5: OWASP ASVS Verification - -Systematic verification against OWASP Application Security Verification Standard (ASVS) 5.0.0 (stable since 2025-05-30). Reference requirements with the version, e.g. `v5.0.0-1.2.5`. - -#### V1: Architecture, Design and Threat Modeling -- Threat model documented and up-to-date -- Security architecture documented -- Trusted/untrusted boundary identification -- Security controls for each component - -#### V2: Authentication -- Password requirements (length, complexity, breach database check) -- Multi-factor authentication implementation -- Credential storage (bcrypt, scrypt, Argon2 - never MD5/SHA1) -- Session fixation prevention -- Account lockout mechanisms -- Credential recovery security - -#### V3: Session Management -- Session ID generation (cryptographically random) -- Session lifecycle (timeout, invalidation) -- Cookie security flags (HttpOnly, Secure, SameSite) -- Session binding to user attributes -- Concurrent session control - -#### V4: Access Control -- Default deny principle -- Function-level access control -- Data-level access control -- JWT access control verification -- OAuth scope validation - -#### V5: Validation, Sanitization and Encoding -- Input validation on all entry points -- Output encoding for context (HTML, JS, URL, SQL) -- Serialization security -- HTTP request smuggling prevention -- Mass assignment protection - -#### V6: Stored Cryptography -- Cryptographic key management -- Encryption algorithms (AES-256, RSA-2048+, never DES/RC4) -- Random number generation (CSPRNG) -- Key rotation procedures -- Certificate validation - -#### V7: Error Handling and Logging -- Error messages don't reveal sensitive info -- Security event logging (auth failures, access violations) -- Log integrity protection -- PII in logs (must be redacted) -- Log injection prevention - -#### V8: Data Protection -- Sensitive data identification and classification -- Data at rest encryption -- Data in transit encryption (TLS 1.2+) -- PII minimization -- Data retention and deletion policies - -#### V9: Communication Security -- TLS configuration (cipher suites, protocols) -- Certificate validation and pinning -- HTTP Strict Transport Security (HSTS) -- DNS security (DNSSEC, CAA records) - -#### V10: Malicious Code -- No backdoors or hidden functionality -- No time bombs or logic bombs -- Anti-tampering mechanisms -- Code obfuscation review (if applicable) - -#### V11: Business Logic -- Business logic flow validation -- Feature abuse prevention -- Automated threat protection (CAPTCHA, rate limiting) -- File upload validation and scanning - -#### V12: Files and Resources -- File upload restrictions (type, size, content) -- File execution prevention -- Path traversal protection -- File inclusion vulnerability prevention - -#### V13: API and Web Service -- API authentication and authorization -- API rate limiting and throttling -- GraphQL introspection disabled in production -- REST API input validation -- WebSocket security - -#### V14: Configuration -- Secure build and deployment configuration -- Unnecessary features/ports/services disabled -- Security headers properly configured -- Error handling configuration -- Production debug mode disabled - -### Phase 6: Regulatory Compliance Analysis - -#### 6.1 LGPD (Lei Geral de Proteção de Dados - Brazil) -- **Data Inventory**: Personal data mapping and classification -- **Legal Basis**: Processing legal basis documented (consent, legitimate interest, etc.) -- **Consent Management**: Granular consent collection, withdrawal mechanism -- **Data Subject Rights**: Access, correction, deletion, portability endpoints -- **DPO Contact**: Data Protection Officer contact information published -- **Cross-Border Transfer**: International data transfer safeguards -- **Breach Notification**: Incident response plan with 72h notification to ANPD -- **Privacy by Design**: Default privacy settings, data minimization -- **Third-Party Processing**: Data processing agreements with processors - -#### 6.2 GDPR (General Data Protection Regulation - EU) -- All LGPD checks apply, plus: -- **Data Protection Impact Assessment (DPIA)**: For high-risk processing -- **Records of Processing Activities (ROPA)**: Documented and maintained -- **Right to be Forgotten**: Automated data deletion capability -- **Data Portability**: Machine-readable export (JSON/CSV) -- **Consent Records**: Timestamped consent with version tracking -- **EU Representative**: Non-EU companies with EU representative appointed -- **Standard Contractual Clauses**: For international transfers - -#### 6.3 SOC 2 Type II -- **Security**: Access controls, logical/physical security -- **Availability**: SLA monitoring, incident management, disaster recovery -- **Processing Integrity**: Input validation, error handling, quality assurance -- **Confidentiality**: Data classification, encryption, access restrictions -- **Privacy**: Collection, use, retention, disclosure, disposal practices -- **Continuous Monitoring**: Automated compliance checks, audit logging -- **Change Management**: Documented change procedures, approval workflows - -#### 6.4 HIPAA (Health Insurance Portability and Accountability Act - US) -- **PHI Identification**: Protected Health Information mapped in codebase -- **Access Controls**: Role-based access to PHI, minimum necessary standard -- **Audit Logging**: All PHI access logged with user, timestamp, action -- **Encryption**: PHI encrypted at rest (AES-256) and in transit (TLS 1.2+) -- **Business Associate Agreements**: BAA with all third-party services handling PHI -- **Breach Notification**: HIPAA-specific breach notification procedures -- **De-identification**: Safe Harbor or Expert Determination methods -- **Integrity Controls**: PHI tampering detection and prevention - -#### 6.5 CCPA/CPRA (California Consumer Privacy Act / Privacy Rights Act) -- **Consumer Rights**: Right to know, delete, opt-out, correct, limit use -- **Sale/Sharing Disclosure**: "Do Not Sell" mechanism if applicable -- **Sensitive Personal Information**: SPI collection with opt-in consent -- **Service Provider Agreements**: CCPA-compliant contracts with processors -- **Data Minimization**: Collection limited to stated purposes -- **Retention Schedules**: Documented retention periods per data category - -### Phase 7: Vibe Coding Heuristics - -Specific heuristic analysis for vulnerability patterns commonly seen in AI-assisted code. CSReview does not prove AI authorship and does not perform deterministic authorship attribution. In the npm engine, `vibeRisk` is a static boolean heuristic attached to selected vulnerability patterns so the report can prioritize issues that commonly appear in rushed agent-generated code. - -#### 7.1 AI-Generated Code Patterns to Detect - -**Authentication & Authorization Bypass:** -- Placeholder authentication (if(true) { next(); }) -- Missing middleware on protected routes -- Client-side-only authentication checks -- Hardcoded bypass flags (DEBUG=true, SKIP_AUTH=true) -- JWT verification disabled or using 'none' algorithm -- Missing token expiration checks - -**Data Exposure Patterns:** -- SELECT * queries exposing all columns including sensitive fields -- API endpoints returning full user objects (including password hashes) -- Missing response filtering/sanitization -- Overly permissive CORS (Access-Control-Allow-Origin: *) -- Database connection strings in client-side code -- API keys in frontend environment variables - -**Injection Vulnerabilities (Common in AI Code):** -- String concatenation in SQL queries (AI often generates this pattern) -- Unsanitized user input in shell commands (exec, spawn, system) -- Template literals with user input (JS template injection) -- Raw HTML rendering (dangerouslySetInnerHTML, v-html, innerHTML) -- Eval-like functions with user data (eval, Function, deserialize) - -**Configuration Mistakes:** -- Default credentials unchanged (admin/admin, root/root) -- Development settings in production (debug=True, verbose logging) -- Missing security headers -- Permissive file upload (any type, any size) -- SSL/TLS verification disabled (NODE_TLS_REJECT_UNAUTHORIZED=0) -- Environment files committed to git - -**Dependency Issues:** -- Outdated or deprecated packages recommended by AI -- Non-existent packages (AI hallucination) -- Packages with known vulnerabilities -- Unnecessary dependencies increasing attack surface -- Mixed package managers (npm + yarn + pnpm) - -#### 7.2 AI-Assisted Development Anti-Patterns - -**Over-Confidence in Security:** -- "This is secure" comments without actual security measures -- Using crypto.createHash('md5') for passwords (AI often suggests this) -- Claiming code is "production-ready" without security review -- Missing error handling with generic catch-all -- Suggesting security-through-obscurity as primary defense - -**Missing Security Thinking:** -- No input validation on user-facing endpoints -- No rate limiting on authentication endpoints -- No logging of security events -- Missing CSRF protection -- No file upload validation -- Missing pagination on list endpoints (DoS vector) - -**Copy-Paste Vulnerabilities:** -- Stack Overflow code with known vulnerabilities -- Tutorial code with intentional security gaps -- Outdated security patterns (MD5, DES, RC4) -- Hardcoded example credentials from documentation - -#### 7.3 Vibe Coding Heuristic Labels - -Each finding may include a "Vibe Risk" flag indicating that the vulnerability matches a pattern often introduced during AI-assisted development. This is a static boolean heuristic in the engine and a prioritization hint for the agent; it does not prove AI authorship. - -| Label | Meaning | Limit | -|-------|---------|-------| -| **Vibe Risk: Yes** | Pattern commonly appears in rushed or AI-assisted code | Not authorship evidence | -| **Vibe Risk: No** | Pattern is not tagged as a vibe-coding heuristic | Not proof the code is human-written | - -### Phase 8: Report Generation - -Generate TWO reports under the selected output directory, normally `/csreview-reports/`. Report files are allowed audit artifacts; they do not mean the CSReview skill was installed inside the project: +Status labels — honest semantics: the built-in probe produces `DAST-SUSPECTED` (anomalous local response requiring human review) and `DAST-CLEAN` (check passed). `DAST-CONFIRMED` is a reserved label for dynamically reproduced evidence from a dedicated local DAST tool the agent ran separately (e.g. OWASP ZAP or Nikto, only when installed, after the same pre-flight and confirmation, against the same confirmed local target) — the built-in probe never emits it. Never probe external hosts, never use destructive payloads or DELETE, and do not send mutating requests without an explicit local allowlist and confirmed data-mutation risk. Full protocol: `reference/local-dast.md`. ---- +## Built-in Code Review Modes -## Report 1: HTML Report (For Humans) - -File: `csreview-reports/_security-report.html` - -### Executive Summary Section -- **Overall Security Score**: 0-100 scale with color coding -- **Severity Distribution**: Pie/bar chart (Critical/High/Medium/Low/Info) -- **Vulnerability Categories**: Bar chart by category -- **Top 5 Critical Findings**: Quick reference cards -- **Risk Assessment**: Overall risk level (Critical/High/Medium/Low) -- **Scan Metadata**: Timestamp, files analyzed, lines scanned - -### Technical Findings Section -For each vulnerability found: +CSReview includes integrated review modes (no extra skills required) — methodology in `reference/review-modes.md`: ``` -┌─────────────────────────────────────────────────┐ -│ [SEVERITY BADGE] Vulnerability Title │ -├─────────────────────────────────────────────────┤ -│ Category: Injection / Auth / Data Leakage / etc │ -│ Location: src/file.ts:142 │ -│ CWE: CWE-89 (SQL Injection) │ -│ │ -│ Description: │ -│ Detailed explanation of the vulnerability │ -│ │ -│ Vulnerable Code: │ -│ [syntax-highlighted code snippet] │ -│ │ -│ Potential Exploitation Path (theoretical, unverified): │ -│ Static-analysis hypothesis; not a validated or executed exploit. │ -│ │ -│ Impact: │ -│ What could happen if exploited │ -│ │ -│ Recommended Fix: │ -│ [syntax-highlighted corrected code] │ -│ │ -│ References: │ -│ OWASP, CVE links, documentation │ -└─────────────────────────────────────────────────┘ +@csreview -> Full security audit (engine + agent passes) +@csreview review [files] -> Standard code review +@csreview adversarial [files] -> Adversarial (red-team) review +@csreview security-review [files] -> Security-focused review of changes +@csreview request-review [PR/branch/commit] -> Review of a change set +@csreview review csreview-reports/codex_security-findings.md -> Plan remediation from a report (CSReview never edits source) ``` -### Report Features -- **Navigation**: Sidebar with anchor links to each finding -- **Filtering**: Filter by severity, category, or status -- **Syntax Highlighting**: Code blocks with language-specific colors -- **Color Coding**: Red=Critical, Orange=High, Yellow=Medium, Blue=Low, Gray=Info -- **Export**: Button to download findings as JSON -- **Print-Friendly**: Optimized CSS for PDF export -- **Responsive**: Works on desktop and mobile - -### HTML Template Structure - -```html - - - - - - Security Audit Report - [Project Name] - - - -
-

Security Audit Report

-
Project: [name] | Date: [timestamp] | Score: [score]/100
-
- - - -
-
- - - - - - - - -
- -
- -
-
- CRITICAL -

SQL Injection in User Authentication

-
-
- Category: Injection - Location: src/auth.ts:45 - CWE: CWE-89 - Vibe Risk: Yes - Compliance: OWASP ASVS V5.3, GDPR Art.32 -
-
-

Description

-

...

-

Vulnerable Code

-
...
-

Potential Exploitation Path (theoretical, unverified)

-

Static-analysis hypothesis only; not a validated or executed exploit.

-

Impact

-

...

-

Recommended Fix

-
...
-

References

-
    ...
-
-
-
- -
- - - - - -
- -
- - - - - -
- -
- - - - - -
- -
- - - -
- -
- - - - - -
-
- -
- -

Generated by CSReview - Code Security Review Skill

-
- - - - -``` - ---- - -## Report 2: Markdown Report (For AI Agents) - -File: `csreview-reports/_security-findings.md` - -This report is structured for humans and AI coding agents to parse, understand, prioritize, and plan remediations. It contains machine-readable findings with exact file locations, vulnerable code evidence, exploitation context, and recommended remediation approaches. It is **not** permission for CSReview to change the audited code. **Always generated in English** regardless of user language. - -### Markdown Structure - -```markdown -# Security Findings Report - -**Project**: [project-name] -**Date**: [YYYY-MM-DD HH:MM:SS] -**Security Score**: [score]/100 -**SLSA Level**: [0-3] -**OWASP ASVS Coverage**: [percentage]% -**Total Findings**: [count] -**Critical**: [count] | **High**: [count] | **Medium**: [count] | **Low**: [count] | **Info**: [count] -**Vibe Coding Heuristics**: [Vibe Risk: count] | [Not flagged: count] - ---- - -## Summary Table - -| ID | Severity | Category | File | Line | Issue | Vibe Risk | Compliance | -|----|----------|----------|------|------|-------|-----------|------------| -| 001 | CRITICAL | SQL Injection | src/auth.ts | 45 | Raw SQL query with user input | Vibe Risk: Yes | ASVS V5.3, GDPR Art.32 | -| 002 | HIGH | XSS | src/components/UserInput.vue | 12 | Unsanitized v-html binding | Vibe Risk: Yes | ASVS V5.2, LGPD Art.46 | -| ... | ... | ... | ... | ... | ... | ... | ... | - ---- - -## Findings - -### Finding #001 - -**Severity**: CRITICAL -**Category**: SQL Injection -**CWE**: CWE-89 -**File**: `src/auth.ts` -**Line**: 45 -**Status**: PENDING -**Vibe Risk**: Yes -**Compliance**: OWASP ASVS V5.3, GDPR Art.32, LGPD Art.46, SOC 2 CC6.1 - -#### Description -Raw SQL query constructed with string concatenation using user-supplied input, allowing SQL injection attacks. - -#### Vulnerable Code -```typescript:src/auth.ts:40-50 -// Lines 40-50 -const query = `SELECT * FROM users WHERE email = '${email}' AND password = '${password}'`; -const result = await db.query(query); -``` - -#### Potential Exploitation Path (theoretical, unverified) -This is a hypothesis derived from static analysis, not a validated or executed exploit. - -1. Attacker submits email: `' OR '1'='1` -2. Query becomes: `SELECT * FROM users WHERE email = '' OR '1'='1' AND password = 'anything'` -3. Authentication bypass achieved - -#### Impact -- Full authentication bypass -- Access to any user account -- Potential data exfiltration via UNION-based injection -- LGPD violation: unauthorized access to personal data (Art.46) -- GDPR violation: inadequate security measures (Art.32) - -#### Fix Required -Replace raw SQL query with parameterized query: - -```typescript:src/auth.ts:40-50 -// FIXED: Use parameterized query -const query = 'SELECT * FROM users WHERE email = $1 AND password = $2'; -const result = await db.query(query, [email, password]); -``` - -#### References -- OWASP: https://owasp.org/www-community/attacks/SQL_Injection -- CWE-89: https://cwe.mitre.org/data/definitions/89.html -- OWASP ASVS V5.3.3: https://owasp.org/www-project-application-security-verification-standard/ - ---- - -## Database Security Findings - -### SQL Database Issues -| ID | Severity | Database | File | Issue | Recommendation | -|----|----------|----------|------|-------|----------------| -| DB001 | CRITICAL | PostgreSQL | src/db.ts:23 | Missing RLS on users table | Enable RLS with user-scoped policies | - -### NoSQL Database Issues -| ID | Severity | Database | File | Issue | Recommendation | -|----|----------|----------|------|-------|----------------| -| DB010 | HIGH | MongoDB | src/models/user.js:15 | NoSQL injection via $gt operator | Use MongoDB driver query builders | - -### BaaS Platform Issues -| ID | Severity | Platform | Config | Issue | Recommendation | -|----|----------|----------|--------|-------|----------------| -| BAAS001 | CRITICAL | Supabase | supabase/config.ts:5 | Service role key in client code | Move to server-side environment | - -### Firebase Cost & Performance Issues -| ID | Severity | Category | File | Issue | Cost Impact | Recommendation | -|----|----------|----------|------|-------|-------------|----------------| -| COST001 | CRITICAL | Firestore Rules | firestore.rules:12 | `allow read, write: if true;` | Unlimited reads/writes = cost explosion | Restrict to authenticated users with resource-level checks | -| COST002 | HIGH | Query | src/hooks/useUsers.ts:23 | `getDocs(collection(db, "users"))` without pagination | Reads entire collection | Add `.limit()` and cursor-based pagination | -| COST003 | HIGH | Cloud Functions | functions/src/index.ts:45 | `onWrite` trigger on high-write collection | Each write = function invocation cost | Filter events or use batch processing | -| COST004 | MEDIUM | Storage | src/utils/upload.ts:15 | No file size limit before upload | Large files = storage + bandwidth cost | Add client-side + server-side size validation | -| COST005 | MEDIUM | Realtime DB | src/App.tsx:30 | `ref.on('value')` on root node | Downloads entire database on every change | Listen to specific paths only | -| COST006 | LOW | Connections | src/context/Auth.tsx:10 | Multiple `onSnapshot` listeners without cleanup | Billed per connection | Unsubscribe on component unmount | - -### .NET / Delphi / Go / Binary Security Issues -| ID | Severity | Category | File | Issue | Recommendation | -|----|----------|----------|------|-------|----------------| -| DOTNET001 | HIGH | ASP.NET | Controllers/AdminController.cs:15 | Missing `[Authorize]` attribute | Add authorization attribute | -| DELPHI001 | CRITICAL | Database | Unit1.pas:45 | Hardcoded Firebird credentials | Use encrypted connection string storage | -| GO001 | HIGH | Web | main.go:67 | SQL injection via `fmt.Sprintf` | Use parameterized queries with `db.Query` | -| DLL001 | MEDIUM | Binary | installer/setup.iss:23 | Missing digital signature | Sign installer with Authenticode certificate | - ---- - -## SLSA Assessment - -| Requirement | Status | Details | -|-------------|--------|---------| -| Source Version Control | [PASS/FAIL] | Git with signed commits | -| Branch Protection | [PASS/FAIL] | Required reviews configured | -| Build Provenance | [PASS/FAIL] | SLSA attestations generated | -| Dependency Pinning | [PASS/FAIL] | Lock files present | -| Artifact Signing | [PASS/FAIL] | Sigstore/cosign configured | - -**Current SLSA Level**: [0-3] -**Recommendations**: [list of actions to reach SLSA Build L3 (v1.2)] - ---- - -## OWASP ASVS Compliance - -| Category | Name | Pass | Fail | N/A | Score | -|----------|------|------|------|-----|-------| -| V1 | Architecture | 5 | 2 | 3 | 71% | -| V2 | Authentication | 8 | 4 | 0 | 67% | -| ... | ... | ... | ... | ... | ... | - -**Overall ASVS Score**: [percentage]% - ---- - -## Compliance Matrix - -### LGPD -| Article | Requirement | Status | Finding Reference | -|---------|-------------|--------|-------------------| -| Art.46 | Security measures | FAIL | #001, #003 | -| Art.48 | Breach notification | PASS | - | - -### GDPR -| Article | Requirement | Status | Finding Reference | -|---------|-------------|--------|-------------------| -| Art.32 | Security of processing | FAIL | #001 | -| Art.25 | Data protection by design | PASS | - | - -### SOC 2 Type II -| Criteria | Requirement | Status | Finding Reference | -|----------|-------------|--------|-------------------| -| CC6.1 | Logical access controls | FAIL | #001, #005 | -| CC6.7 | Data transmission | PASS | - | - -### HIPAA -| Safeguard | Requirement | Status | Finding Reference | -|-----------|-------------|--------|-------------------| -| 164.312(a) | Access control | FAIL | #002 | -| 164.312(e) | Transmission security | PASS | - | - -### CCPA/CPRA -| Section | Requirement | Status | Finding Reference | -|---------|-------------|--------|-------------------| -| 1798.100 | Right to know | FAIL | Missing endpoint | -| 1798.105 | Right to delete | PASS | - | - ---- - -## Vibe Coding Assessment - -### Vibe-Risk Findings -Findings matching vulnerability patterns that commonly appear in rushed or AI-assisted code. This does not prove AI authorship. - -| ID | Pattern | Heuristic | Recommendation | -|----|---------|-----------|----------------| -| 001 | String concatenation SQL | Vibe Risk: Yes | Replace with parameterized queries | -| 003 | MD5 password hashing | Vibe Risk: Yes | Switch to bcrypt/Argon2 | - -### AI-Assisted Code Quality Notes -- **Security Awareness**: [Low/Medium/High] -- **Common AI Anti-Patterns Found**: [count] -- **Recommendation**: [brief guidance for the user] - ---- - -## Fix Priority Order - -Apply fixes in this order: - -1. **CRITICAL findings first**: Authentication bypass, SQL injection, RCE, exposed secrets -2. **HIGH findings second**: XSS, CSRF, IDOR, missing authorization -3. **MEDIUM findings third**: CORS misconfiguration, insecure headers, rate limiting -4. **LOW findings fourth**: Defense-in-depth improvements, best practices -5. **INFO findings last**: Recommendations, documentation updates +## When to Invoke -Within each severity, prioritize by: -1. Vibe-risk findings (patterns often repeated in rushed or AI-assisted code) -2. Compliance-critical findings (regulatory violations) -3. Database security issues -4. Supply chain concerns +- User requests a security review, code audit, vulnerability scan, or pentest-style static analysis +- User asks about exposed secrets, data leakage, SQL injection, XSS, or auth flaws +- Pre-release/deployment review of the local workspace; Supabase/Firebase/Appwrite/BaaS rule review +- Compliance correlation requests (LGPD, GDPR, SOC 2, HIPAA); vibe-coding verification of AI-written code +- Any `@csreview ...` invocation listed above -## Agent Instructions +## Supported Technologies -When fixing these findings (note: CSReview only reports; the coding agent or developer applies fixes): +Frontend (React, Vue, Nuxt, Angular, Svelte, Next.js), mobile (Flutter, Kotlin/Android, Swift/iOS, React Native), backend (Node.js, Python, C#/.NET, Go, Java, PHP, Ruby), systems (C, C++, Rust), desktop (Electron, Tauri), Delphi/Lazarus/Free Pascal, SQL/NoSQL databases, BaaS platforms (Supabase, Firebase, Appwrite, Neon, PocketBase, Convex, and similar), installers/DLLs/binaries, and OS-specific surfaces (macOS, iOS, Linux, Windows). Detection depth varies by stack: language-specific engine rules exist for JavaScript/TypeScript, Python, C#, Go, C/C++, and Delphi; other stacks rely on Semgrep, OSV-Scanner, and the agent checklists in `reference/security-checklists.md`. -1. Read the vulnerable file at the specified line numbers -2. Understand the context before applying the fix -3. If the framework is unfamiliar, research official documentation before applying fixes -4. Treat the recommendation as guidance, not a patch; inspect the framework, schema, tests, and surrounding code before changing anything -5. Verify the fix doesn't break existing functionality -6. Mark the finding as FIXED after successful application -7. Run tests to ensure no regressions -8. Commit changes with descriptive message: `fix(security): [brief description of fix]` -9. After all fixes, re-run CSReview to verify remediation -``` +### AI Agent Compatibility ---- +| Agent | Integration | +|-------|-------------| +| Claude Code | Global skill via `~/.claude/skills/csreview/SKILL.md` | +| Codex | Global skill via `~/.codex/skills/csreview/SKILL.md` or `~/.agents/skills/csreview/SKILL.md` | +| Trae / SOLO | Global skill via `~/.trae/skills/csreview/SKILL.md` | +| OpenCode / Qwen CLI / Antigravity / Qoder / Cursor / Windsurf / Cline / Copilot CLI / Aider | Compatible via each agent's global rules/instructions mechanism when supported | -## Severity Classification - -| Severity | Criteria | Response Time | -|----------|----------|---------------| -| **Critical** | Direct data breach, RCE, auth bypass, exposed PII | Immediate fix required | -| **High** | Significant vulnerability, exploitable with effort | Fix within 24-48h | -| **Medium** | Moderate risk, requires specific conditions | Fix within 1 week | -| **Low** | Minor issue, defense-in-depth improvement | Fix in next sprint | -| **Info** | Best practice recommendation, no direct risk | Consider for improvement | - -## Built-in Code Review System - -CSReview includes a complete code review system that eliminates the need for external review skills. This system provides 5 integrated review modes: - -### Review Mode 1: Standard Code Review (`codex:review` equivalent) - -Comprehensive code review covering: - -**Code Quality:** -- Code readability and maintainability -- Naming conventions consistency -- Function/method complexity (cyclomatic complexity) -- Dead code detection -- Code duplication identification -- SOLID principles adherence -- DRY principle violations -- Separation of concerns - -**Architecture:** -- Design pattern appropriateness -- Module coupling analysis -- Dependency direction violations -- Interface segregation -- Single responsibility violations - -**Performance:** -- Algorithm complexity (O(n) analysis) -- Memory leak potential -- Unnecessary object creation -- Database query optimization (N+1 queries) -- Caching opportunities -- Bundle size impact - -**Testing:** -- Test coverage gaps -- Missing edge case tests -- Test isolation issues -- Mock overuse detection -- Missing integration tests - -**Documentation:** -- Missing JSDoc/docstrings on public APIs -- Outdated comments -- Missing README sections -- Undocumented breaking changes - -### Review Mode 2: Adversarial Review (`codex:adversarial-review` equivalent) - -Red-team mindset review that actively tries to break the code: - -**Attack Vectors:** -- Boundary condition exploitation -- Race condition identification -- Resource exhaustion scenarios -- Error handling bypass attempts -- State corruption possibilities -- Input validation gaps at every boundary - -**Failure Modes:** -- What happens when external services are down? -- What happens with malformed input at each layer? -- What happens under extreme load? -- What happens with concurrent modifications? -- What happens when disk/memory is full? - -**Edge Cases:** -- Empty/null/undefined inputs -- Maximum size inputs -- Unicode/special characters -- Timezone-sensitive operations -- Floating point precision issues -- Integer overflow scenarios - -**Adversarial Questions:** -- "How can I make this code fail?" -- "What's the worst input an attacker could provide?" -- "What assumptions does this code make that could be wrong?" -- "What happens if I remove this check?" -- "Can I bypass this validation?" - -### Review Mode 3: Security-Focused Code Review (`code-review` equivalent) - -Security-specific review integrated with the main CSReview analysis: - -- All Phase 2 (Ultra-Deep Security) checks applied to specific code changes -- All Phase 3 (Database Security) checks for data layer changes -- All Phase 7 (Vibe Coding) pattern detection for AI-generated code -- Security impact assessment of each change -- Threat model updates required for architectural changes - -### Review Mode 4: Requesting Code Review (`requesting-code-review` equivalent) - -When a developer or coding agent requests a review: - -**Review Request Protocol:** -1. Identify the scope of changes (files, functions, modules) -2. Determine review depth (quick scan, standard, deep) -3. Select applicable review modes (quality, adversarial, security) -4. Generate review checklist based on change type -5. Execute review and generate findings -6. Prioritize findings by severity and actionability - -**Change-Type Detection:** -- **New feature**: Full review with adversarial testing -- **Bug fix**: Verify fix correctness, check for regression -- **Refactoring**: Verify behavior preservation, check for missed cases -- **Configuration change**: Security impact assessment -- **Dependency update**: Vulnerability and license check -- **Database migration**: Data integrity and rollback assessment - -### Review Mode 5: Receiving Code Review (`receiving-code-review` equivalent) - -When CSReview findings are received by a coding agent: - -**Response Protocol:** -1. Parse findings from the MD report -2. Categorize by severity and type -3. For each finding: - - Acknowledge the issue - - Research the fix (if framework is unfamiliar, consult official docs) - - Propose a solution - - Apply the fix (coding agent responsibility) - - Verify the fix doesn't introduce new issues -4. Report back with summary of changes made - -**Fix Verification Checklist:** -- [ ] Fix addresses the specific vulnerability -- [ ] Fix doesn't break existing functionality -- [ ] Fix follows framework best practices -- [ ] Fix doesn't introduce new vulnerabilities -- [ ] Fix includes appropriate tests (if applicable) -- [ ] Fix is documented (if behavior changes) - -### Integrated Review Workflow - -When CSReview is invoked, it can operate in any of these modes: +Regardless of agent: the HTML report is generated for the user (human review); the MD report is always English for agent consumption; behavior and report formats stay consistent. -``` -@csreview → Full 8-phase security audit -@csreview review [files] → Standard code review (Mode 1) -@csreview adversarial [files] → Adversarial review (Mode 2) -@csreview security-review [files] → Security code review (Mode 3) -@csreview request-review [PR/branch/commit] → Request review of changes (Mode 4) -@csreview review csreview-reports/codex_security-findings.md → Plan remediation from report without CSReview editing source code -``` +## Output -## Execution Workflow +- **Primary**: `csreview-reports/_security-report.html` — visual report for human review +- **Secondary**: `csreview-reports/_security-findings.md` — structured English report for remediation planning +- **CI**: `csreview-reports/_security.sarif` — SARIF 2.1.0 (pair with `--fail-on`) +- **Verbal**: summary of CRITICAL/HIGH findings, mode, and disclosed gaps; JSON export available from the HTML report -When invoked, follow these steps: - -1. **Confirm global skill scope**: If the task involves installing or updating CSReview itself, use the agent's global skills directory by default. Do not install CSReview into the analyzed project unless the user explicitly requested project-local installation. -2. **Announce the scan**: Inform user about starting security analysis -3. **Phase 0 - Tool Detection**: Attempt Semgrep first (`semgrep --version`, then `semgrep --config auto --json --quiet `). Then attempt read-only dependency scanners (`pnpm audit --json` when `pnpm-lock.yaml` exists, otherwise `npm audit --json` for npm lockfiles, plus `osv-scanner scan --format json ` when installed). Detect installed framework/security tools (bandit, trivy, snyk, gosec, eslint, codeql, pip-audit, etc.). Report which tools are available and which are missing. Run all available relevant tools against the project. Normalize tool output into unified findings format. -4. **Phase 1 - Recon**: Scan project structure, identify technologies, map attack surface -5. **Phase 2 - Deep Analysis**: Systematically check each vulnerability category (injection, auth, data leakage, XSS, CSRF, config, deps, cloud, .NET, Delphi/Lazarus, Go, DLL/installer, platform-specific, logic flaws) -6. **Phase 3 - Database Security**: Analyze SQL/NoSQL/BaaS database structures, access patterns, Firebase cost/performance, and configurations -7. **Phase 4 - SLSA Build L3 (v1.2)**: Assess supply chain integrity (source, build, dependency, deployment) -8. **Phase 5 - OWASP ASVS**: Systematic verification against V1-V14 categories -9. **Phase 6 - Compliance**: Check LGPD, GDPR, SOC 2, HIPAA, CCPA-CPRA requirements -10. **Phase 7 - Vibe Coding**: Flag static heuristics for vulnerability patterns commonly seen in rushed or AI-assisted code -11. **Progress updates**: Keep user informed of analysis progress throughout -12. **Phase 8 - Report Generation**: Create BOTH reports: - - `csreview-reports/_security-report.html` (visual report in user's language for human review) - - `csreview-reports/_security-findings.md` (structured report in English for human/coding-agent remediation planning) -13. **Deliver reports**: Provide absolute paths to both generated files: - - HTML report path for the user to click/open in a browser - - Markdown report path for the coding agent to analyze before remediation -14. **Summary**: Give brief verbal summary of critical/high findings including tool-detected vs AI-estimated findings, compliance gaps, vibe coding risks, and Firebase cost issues -15. **Offer next step**: Ask whether the user wants a prioritized remediation plan or wants a separate coding agent session to apply selected fixes with project-context validation. - -## Important Guidelines - -- **READ-ONLY**: CSReview NEVER modifies, deletes, moves, or creates source code in the analyzed project. It only identifies, reports, and suggests remediation approaches. -- **Global Installation Default**: CSReview MUST be installed in the agent's global skill/instruction environment by default. Do not place CSReview skill files in the analyzed project unless the user explicitly requested project-local installation. -- **Tool Detection First**: ALWAYS run Phase 0 (tool detection) before any analysis. The user must know which mode is active. -- **Agent-Only Risk Disclosure**: When operating in Agent-Only mode, the agent MUST explicitly warn the user that findings have lower confidence and that real security tools should be installed for production audits. A less knowledgeable agent may miss critical vulnerabilities or produce incorrect recommendations. -- **Semgrep Required Baseline**: Always attempt to run `semgrep` (universal) and the language-specific primary tool for the project being analyzed. If Semgrep is missing, mark the run lower-confidence and provide installation commands. -- **Dependency SCA Complement**: Run `pnpm audit --json` for Node.js roots with `pnpm-lock.yaml`, otherwise run `npm audit --json` for npm lockfiles. Also run `osv-scanner scan --format json ` when OSV-Scanner is installed. Never run dependency fix/update commands during CSReview. -- **External Research Required When Uncertain**: If the agent is unsure about framework behavior, safe configuration, version-specific APIs, exploitability, or remediation, it MUST search external sources before making a confident claim. Use official framework documentation first, then vendor security advisories and specialized security sources such as OWASP, CWE, CVE/NVD, GitHub Security Advisories, OSV.dev, and Snyk. Do not guess. -- **All Relevant Files Are Scanned**: All relevant in-scope files are scanned; generated, vendor, minified, and IDE directories (e.g. `dist`, `build`, `vendor`, `bin`, `obj`, `.next`, `node_modules`, `.git`) and the generated reports are excluded. Do not rely on sampling for in-scope source. -- **Never expose secrets in chat**: If you find hardcoded credentials, mention them in the reports only, not in the conversation -- **Be thorough but practical**: Focus on exploitable vulnerabilities, not theoretical edge cases -- **Provide actionable remediation**: Every finding must include concrete remediation guidance, but the fix is applied by the human developer or coding agent after reviewing context, not by CSReview. -- **Context matters**: Consider the application type (internal tool vs public API) when assessing severity -- **False positives**: Only report confirmed vulnerabilities, avoid noise -- **Prioritize**: Critical and High findings should be clearly highlighted -- **Respect scope**: Only analyze code in the specified project, don't test external services -- **MD report precision**: File paths and line numbers in the MD report must be exact so humans or coding agents can safely inspect and plan remediation. -- **HTML report language**: Generate the HTML report in the same language as the user's conversation language -- **MD report language**: Always generate the MD report in English regardless of user language (for agent consumption) -- **Compliance findings**: Clearly map each compliance gap to the specific regulation article/section -- **Vibe coding markers**: Tag findings with a Vibe Risk boolean (Yes/No). This is a heuristic signal, not a numeric score and not proof of AI authorship. -- **Database findings**: Include specific database engine version requirements when relevant -- **SLSA scoring**: Clearly indicate current SLSA level and what's needed to reach level 3 -- **Unknown frameworks**: If the analyzed code uses a framework the agent is not familiar with (e.g., Lazarus, Delphi, niche frameworks), the agent MUST research using official documentation from the framework's official website, database vendor documentation, and community forums before reporting findings and suggesting fixes -- **Documentation sourcing**: For each finding, reference the official documentation of the relevant framework, database, or platform (e.g., PostgreSQL docs, Supabase docs, Firebase docs, Appwrite docs, MongoDB docs, etc.) -- **Forum research**: When encountering unusual errors or obscure vulnerabilities, search relevant community forums (Stack Overflow, GitHub Issues, framework-specific forums) to provide accurate, tested solutions -- **Transparency**: Report all steps taken during the analysis, including what was checked, what was found, and what research was conducted to arrive at recommendations - -## Example Invocation - -User: "Run a security review on this project" -User: "Check for vulnerabilities in my Supabase backend" -User: "Audit this code for data leakage" -User: "Do a pentest analysis before deployment" -User: "Find any SQL injection or XSS vulnerabilities" -User: "Verify LGPD and GDPR compliance in my codebase" -User: "Check if my code has vibe coding vulnerabilities" -User: "Analyze my database security for PostgreSQL and MongoDB" -User: "Run OWASP ASVS verification on this project" -User: "Check supply chain security (SLSA)" -User: "@csreview" -User: "@csreview review src/auth.ts src/middleware/" -User: "@csreview adversarial src/api/payments/" -User: "@csreview security-review src/components/" -User: "@csreview request-review main..feature/auth" -User: "@csreview review csreview-reports/codex_security-findings.md" +## Reference Index -## Output +Load these on demand; they are reference material, not standing instructions: -- **Primary**: `csreview-reports/_security-report.html` under the selected output directory (visual report in user's language for human review) -- **Secondary**: `csreview-reports/_security-findings.md` under the selected output directory (structured report in English for remediation planning) -- **Tertiary**: Verbal summary of critical/high findings in chat including compliance gaps and vibe coding risks -- **Optional**: JSON export available via HTML report button +- `reference/security-checklists.md` — contextual review checklists (injection, auth, BaaS, platform-specific, database, Firebase cost) +- `reference/compliance-frameworks.md` — SLSA / ASVS / LGPD / GDPR / SOC 2 / HIPAA / CCPA correlation (and what the engine does NOT compute) +- `reference/tooling.md` — tool detection, read-only invocation forms, installation pointers +- `reference/subagents.md` — scatter-gather protocol detail and partial-file contract +- `reference/local-dast.md` — Phase 9 protocol detail and guard semantics +- `reference/review-modes.md` — the five review-mode methodologies +- `reference/reports.md` — actual report anatomy and the canonical finding schema diff --git a/csreview/package.json b/csreview/package.json index 6bb8298..7b4d9a9 100644 --- a/csreview/package.json +++ b/csreview/package.json @@ -29,6 +29,7 @@ "license": "MIT", "files": [ "src/", + "reference/", "SKILL.md", "README.md", "LICENSE" diff --git a/csreview/reference/compliance-frameworks.md b/csreview/reference/compliance-frameworks.md new file mode 100644 index 0000000..6aaa696 --- /dev/null +++ b/csreview/reference/compliance-frameworks.md @@ -0,0 +1,103 @@ +# CSReview Reference - Compliance & Framework Correlation + +**Honesty contract**: the engine maps findings to the frameworks below by CWE +correlation only (see `COMPLIANCE_MAP` in `src/detector.js`). It does NOT +compute per-article PASS/FAIL verdicts, ASVS coverage percentages, or SLSA +levels, and the agent MUST NOT fabricate such numbers in summaries. Per-article +or per-requirement assessments may appear in a report only when a human or the +agent explicitly evaluated that requirement against the workspace and says so. +Compliance output is **indicative correlation, not an audited compliance +verification**. + +## SLSA Supply Chain Review (SLSA Build L3, v1.2) + +Checklist for the agent's supply-chain review. Reference requirements with +track + level + version (e.g. "SLSA Build L3 (v1.2)"). + +**Source integrity**: signed commits, branch protection, required reviews, +CODEOWNERS, repository permission audit, 2FA enforcement. + +**Build integrity**: automated CI/CD, reproducible/hermetic builds, hosted build +service, signed build attestations/provenance, artifact signing +(Sigstore/cosign/GPG), base image verification. + +**Dependency security**: lock files present and committed, exact version +pinning, integrity hashes, SBOM generation and maintenance, automated +vulnerability scanning, typosquatting review, license audit. + +**Deployment security**: dev/staging/production separation, secrets in a +vault/manager (not code or committed env files), restricted and audited +deployment access, rollback capability, audited IaC templates. + +## OWASP ASVS 5.0.0 Review Areas + +Systematic verification areas from the OWASP Application Security Verification +Standard 5.0.0 (stable since 2025-05-30). Reference requirements with the +version, e.g. `v5.0.0-1.2.5`. The engine's `COMPLIANCE_MAP` correlates CWEs to +ASVS chapters; chapter-by-chapter verification is agent/human work. + +- **V1 Architecture**: threat model, security architecture, trust boundaries +- **V2 Authentication**: password policy, MFA, credential storage + (bcrypt/scrypt/Argon2 — never MD5/SHA1), lockout, recovery +- **V3 Session Management**: random session IDs, lifecycle/timeout, cookie + flags (HttpOnly/Secure/SameSite), session binding +- **V4 Access Control**: default deny, function-level and data-level checks, + JWT verification, OAuth scopes +- **V5 Validation & Encoding**: input validation at every entry point, + context-aware output encoding, deserialization safety, mass assignment +- **V6 Stored Cryptography**: key management, modern algorithms (AES-256, + RSA-2048+; never DES/RC4), CSPRNG, key rotation +- **V7 Errors & Logging**: no sensitive info in errors, security event logging, + log integrity, PII redaction, log injection prevention +- **V8 Data Protection**: classification, encryption at rest and in transit + (TLS 1.2+), PII minimization, retention/deletion +- **V9 Communication**: TLS configuration, certificate validation/pinning, HSTS +- **V10 Malicious Code**: no backdoors/time bombs, anti-tampering +- **V11 Business Logic**: flow validation, abuse prevention, rate limiting +- **V12 Files & Resources**: upload restrictions, execution prevention, path + traversal protection +- **V13 API & Web Services**: API authn/authz, rate limiting, GraphQL + introspection off in production, WebSocket security +- **V14 Configuration**: secure build/deploy, security headers, debug off in + production + +## Regulatory Correlation Checklists + +These lists support the agent when the user asks for a privacy/compliance +review. Many items are process/documentation controls that cannot be verified +from source code alone — say so explicitly instead of guessing. + +### LGPD (Brazil) + +Data inventory and classification; documented legal basis; granular consent and +withdrawal; data subject rights endpoints (access, correction, deletion, +portability); DPO contact; cross-border transfer safeguards; 72h ANPD breach +notification plan; privacy by design/default; processor agreements. + +### GDPR (EU) + +LGPD items plus: DPIA for high-risk processing; records of processing (ROPA); +right to be forgotten (automated deletion); machine-readable data portability; +timestamped, versioned consent records; EU representative for non-EU companies; +SCCs for international transfers. + +### SOC 2 Type II + +Security (access controls), availability (SLA monitoring, DR), processing +integrity (validation, error handling), confidentiality (classification, +encryption), privacy (collection/use/retention/disposal), continuous monitoring +and audit logging, change management. + +### HIPAA (US) + +PHI mapping in the codebase; role-based access with minimum-necessary; audit +logging of PHI access; AES-256 at rest and TLS 1.2+ in transit; BAAs with third +parties handling PHI; HIPAA-specific breach procedures; de-identification +methods; integrity controls. (BAA and similar contractual controls are process +items — not verifiable from code.) + +### CCPA/CPRA (California) + +Right to know/delete/opt-out/correct/limit; "Do Not Sell" mechanism when +applicable; opt-in for sensitive personal information; service provider +agreements; data minimization; documented retention schedules. diff --git a/csreview/reference/local-dast.md b/csreview/reference/local-dast.md new file mode 100644 index 0000000..4f8a3e2 --- /dev/null +++ b/csreview/reference/local-dast.md @@ -0,0 +1,58 @@ +# CSReview Reference - Phase 9 Optional Local DAST + +Full protocol for the optional, post-remediation, local-only dynamic +complement. The core rules and the required user-facing confirmation prompt +live in SKILL.md; this file holds the operational detail. + +## What the built-in probe actually does + +`csreview --local-dast-url --confirm-local-dast` performs a +conservative, non-mutating HTTP check against the confirmed loopback target: +reachability, browser security headers (Content-Security-Policy, +X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy), +and CORS behavior against a hostile origin. It is **not** a penetration test, +it never follows redirects, and it aborts immediately if a response points to +an external host. + +## Engine guards (enforced in code, not just documented) + +- Target hostname must be `localhost`, `127.0.0.1`, or `[::1]`; anything else + is rejected before any request. +- `--confirm-local-dast` is required; without it the run stops with the + confirmation instructions. +- Redirects are not followed (`redirect: manual`); an external `Location` + aborts the phase. +- Reports are written only inside `csreview-reports/`. +- An advisory pre-flight scans `.env`, `.env.local`, and `.env.development` for + external hosts and surfaces them as `DAST-SUSPECTED` so you can verify the + local app does not proxy probe traffic outward. It is advisory because real + development env files almost always reference external services. + +## Status labels (honest semantics) + +- `DAST-SUSPECTED` — anomalous local response that requires human review. +- `DAST-CLEAN` — the checked condition passed for the local target. +- `DAST-CONFIRMED` — **reserved label, never produced by the built-in probe.** + It may only appear when a dedicated local DAST tool (run separately by the + agent, e.g. OWASP ZAP or Nikto against the same confirmed loopback target, + after the same pre-flight and confirmation) dynamically reproduced an issue + with clear evidence. If no such tool ran, no finding may carry this label. + +## Outputs + +- `csreview-reports/_local-dast-report.html` +- `csreview-reports/_local-dast-findings.md` +- With a run ID: timestamped history copies + (`_local-dast-report-.html` / `...-findings-.md`) so + re-running after remediation never overwrites prior evidence. +- `_db-dump-guide.html` — a read-only, per-backend guide for preparing + an isolated local database copy BEFORE any database-level testing (schema-only + dumps, synthetic users, zero real PII; never dump production). + +## Hard limits + +Never probe external IPs, domains, staging, or production. Never use +destructive payloads or DELETE. Do not send mutating POST/PUT/PATCH unless the +user provided an explicit local test endpoint allowlist and confirmed the data +mutation risk. If the test uses a database copy, it must be deliberately +created, stored securely, and sanitized or minimized where needed. diff --git a/csreview/reference/reports.md b/csreview/reference/reports.md new file mode 100644 index 0000000..8b0ef37 --- /dev/null +++ b/csreview/reference/reports.md @@ -0,0 +1,74 @@ +# CSReview Reference - What the Engine Reports Actually Contain + +The engine writes every report deterministically. The agent never handcrafts +report files and never invents metrics that the engine does not compute. In +particular there is **no** "ASVS coverage %", "SLSA level", or per-article +compliance PASS/FAIL anywhere in the generated reports — see +`reference/compliance-frameworks.md` for what compliance correlation means. + +## HTML report (`_security-report.html`) + +For human review, generated in a self-contained file: executive summary with +the 0-100 score (severity-capped: any CRITICAL caps it at 49, any HIGH at 74), +severity and category charts, findings-by-origin breakdown (which tool reported +what, corroborated findings first), tool execution status (which engine tools +ran, versions, raw counts), filterable finding cards (severity, category, file +search), per-finding metadata (CWE link, OWASP category, confidence, compliance +correlation, vibe-risk flag, redacted evidence snippet, theoretical +exploitation hypothesis, remediation guidance, references), and an "Export as +JSON" button. Secrets are redacted before rendering; all dynamic content is +HTML-escaped. + +## Markdown report (`_security-findings.md`) + +For coding agents (always English). Actual sections emitted by the engine: + +1. **Executive Summary** — score, totals by severity, mode, tool status +2. **Findings Index** — table of every finding with file:line +3. **Detailed Findings** — full canonical finding objects +4. **Category Analysis** — counts and highlights per category +5. **Compliance Impact** — CWE-correlated framework references (indicative) +6. **Fix Priority Order** — Immediate (CRITICAL) → Short-term (HIGH) → + Medium-term (MEDIUM) → Low Priority (LOW/INFO) +7. **Remediation Guidance** — per-finding guidance, never an exact patch to + apply blindly +8. **Scan Metadata** — timestamps, file counts, tool versions, suppression and + baseline counts + +## SARIF report (`_security.sarif`) + +SARIF 2.1.0 for CI and GitHub code scanning. It never embeds raw vulnerable +code, so secrets are not leaked into uploaded artifacts. Pair it with +`--fail-on ` to gate merges. + +## Canonical finding schema + +Exchanged by the detector, tool normalizers, subagent partials, and all report +generators: + +```json +{ + "id": "SQL_INJECTION_src-auth-ts_45", + "severity": "CRITICAL|HIGH|MEDIUM|LOW|INFO", + "category": "Injection", + "name": "...", + "description": "...", + "file": "src/auth.ts", + "line": 45, + "vulnerableCode": "redacted/snippet", + "cwe": "CWE-89", + "owasp": "A03:2021-Injection", + "fix": "...", + "confidence": "CONFIRMED|TOOL-ONLY|HIGH|MEDIUM|LOW", + "exploitation": "theoretical hypothesis, never a validated exploit", + "references": ["https://..."], + "source": "csreview-detector|semgrep|npm-audit|pnpm-audit|bun-audit|osv-scanner|gitleaks|trivy|gosec|bandit|subagent:", + "vibeRisk": false, + "compliance": "OWASP ASVS V5.3, GDPR Art.32 (CWE correlation)" +} +``` + +Confidence semantics: `CONFIRMED` = corroborated by more than one independent +source (e.g. detector + Semgrep at the same file:line:CWE); `TOOL-ONLY` = one +external tool; `HIGH|MEDIUM|LOW` = heuristic detector confidence. Findings in +test/fixture/example paths are downgraded to LOW instead of hidden. diff --git a/csreview/reference/review-modes.md b/csreview/reference/review-modes.md new file mode 100644 index 0000000..0c4ebf5 --- /dev/null +++ b/csreview/reference/review-modes.md @@ -0,0 +1,52 @@ +# CSReview Reference - Code Review Modes + +Detail for the five review modes summarized in SKILL.md. These are agent +methodologies layered on top of the engine run; they do not change what the +engine writes. + +## Mode 1 - Standard Code Review (`@csreview review [files]`) + +Quality: readability, naming, complexity, dead code, duplication, SOLID/DRY, +separation of concerns. Architecture: pattern fit, coupling, dependency +direction. Performance: algorithmic complexity, leaks, N+1 queries, caching, +bundle impact. Testing: coverage gaps, missing edge cases, isolation, mock +overuse. Documentation: missing docstrings on public APIs, stale comments, +undocumented breaking changes. + +## Mode 2 - Adversarial Review (`@csreview adversarial [files]`) + +Red-team mindset: actively try to break the change. Boundary exploitation, +race conditions, resource exhaustion, error-handling bypass, state corruption, +validation gaps at every layer. Failure modes: external service down, malformed +input, extreme load, concurrent modification, full disk/memory. Edge cases: +empty/null, maximum sizes, Unicode, timezones, float precision, integer +overflow. Ask: "How can I make this fail?", "What is the worst input?", "What +assumption can be wrong?", "Can I bypass this check?" + +## Mode 3 - Security-Focused Review (`@csreview security-review [files]`) + +Apply the security and database checklists (see +`reference/security-checklists.md`) to the specific changed files, assess the +security impact of each change, and flag architectural changes that require +threat-model updates. Vibe-risk heuristics from the engine apply here. + +## Mode 4 - Requesting a Review (`@csreview request-review [scope]`) + +Protocol: identify scope (files/functions/modules) → choose depth → select +modes (quality/adversarial/security) → build a checklist for the change type → +execute → prioritize by severity and actionability. Change types: new feature +(full + adversarial), bug fix (correctness + regression), refactor (behavior +preservation), configuration (security impact), dependency update +(vulnerability + license), migration (integrity + rollback). + +## Mode 5 - Receiving Review Findings + +(`@csreview review csreview-reports/codex_security-findings.md`) + +Parse the Markdown report → categorize by severity → for each finding: +acknowledge, research the fix (official docs first), propose, apply (coding +agent's responsibility, never CSReview's), verify nothing new broke. Fix +verification checklist: addresses the specific vulnerability; preserves +behavior; follows framework practice; introduces no new issues; tested; +documented when behavior changes. After all fixes, re-run the engine — +optionally with `--baseline` so only NEW findings fail CI. diff --git a/csreview/reference/security-checklists.md b/csreview/reference/security-checklists.md new file mode 100644 index 0000000..b6a1cee --- /dev/null +++ b/csreview/reference/security-checklists.md @@ -0,0 +1,199 @@ +# CSReview Reference - Security Review Checklists + +Reference material for the agent's contextual review pass (after the engine run). +These checklists guide what to LOOK FOR when reading flagged files and their +surroundings. They are not detector rules: the deterministic engine and the +external tools report what they detect; the agent uses these lists to reason +about context the tools cannot see. + +## Injection Vulnerabilities + +- **SQL Injection**: raw queries, string concatenation, ORM misuse +- **NoSQL Injection**: MongoDB operator injection, Redis command injection +- **Command Injection**: exec(), system(), subprocess calls with user input +- **LDAP / XPath Injection**: directory and XML query manipulation +- **Template Injection**: SSTI in Jinja2, Twig, EJS, and similar engines + +## Authentication & Authorization + +- **JWT flaws**: missing validation, weak secrets, algorithm confusion +- **Session management**: insecure cookies, missing HttpOnly/Secure flags +- **RLS policies**: missing or bypassable Row Level Security (Supabase/Postgres) +- **Role-based access**: privilege escalation, missing authorization checks +- **IDOR**: insecure direct object references exposing other users' data +- **OAuth/OpenID**: misconfigured flows, token leakage, redirect URI flaws + +## Data Leakage + +- Sensitive data in console.log/logger/error messages; stack traces shown to users +- PII in API responses without filtering; debug endpoints enabled in production +- Server/framework version disclosure in headers; sensitive data cached in browser/CDN + +## Cross-Site Vulnerabilities + +- **XSS**: reflected, stored, DOM-based (dangerouslySetInnerHTML, v-html, innerHTML) +- **CSRF**: missing tokens, SameSite cookie misconfiguration +- **CORS**: overly permissive origins, wildcard Access-Control-Allow-Origin +- **Clickjacking**: missing X-Frame-Options or CSP frame-ancestors + +## Insecure Configurations + +- Missing security headers (CSP, HSTS, X-Content-Type-Options) +- Weak TLS ciphers, missing certificate pinning, HTTP fallback +- File uploads without type/size validation; path traversal in file operations +- Missing rate limiting on authentication and expensive endpoints +- Verbose error handling and information disclosure + +## Dependency & Supply Chain + +- Known CVEs in dependencies (engine: package audit + OSV-Scanner) +- Suspicious packages, typosquatting, compromised or hallucinated dependencies +- Restrictive licenses in production dependencies + +## Cloud & BaaS Backends + +**Supabase**: missing RLS on sensitive tables; `allow all authenticated` policies; +service role key in client code; public storage buckets; edge functions without +auth; realtime subscriptions without authorization; missing webhook validation. + +**Firebase/Firestore**: rules allowing unauthenticated read/write; rules without +`request.auth` checks; storage rules without file type/size validation; missing +App Check; API keys with excessive permissions; functions without auth; missing +subcollection rules. + +**Appwrite**: collection permissions set to `any`; missing attribute validation; +function execution without auth; broad storage permissions; missing webhook +signature validation; over-scoped API keys. + +**Neon**: connection strings with credentials in code; missing SSL/TLS +enforcement; unrestricted branch access; missing RLS. + +**PocketBase**: default admin credentials; permissive collection rules; missing +field encryption; upload rules without validation; missing rate limiting. + +**Convex**: missing authentication in functions; broad document access; missing +mutation validation; sensitive data in logged function arguments. + +## Firebase Cost & Performance Patterns + +Cost-relevant patterns the agent should flag when reviewing Firebase projects +(report them as findings with cost impact context): + +**Rules**: `allow read, write: if true;` (cost explosion); `allow read: if +request.auth != null;` on whole collections; root-level `.read/.write: true` in +Realtime Database; missing `request.resource.size` limits; `allow list` without +`request.query.limit`. + +**Queries**: `getDocs(collection(...))` without `.limit()` or pagination; +missing cursors (`startAfter`/`endBefore`); `onSnapshot` listeners without +unsubscribe; `getDocs()` inside loops (N+1); reading whole documents when few +fields are needed; `ref.once('value')` on root or large nodes. + +**Cloud Functions**: `onWrite`/`onCreate` triggers on high-write collections; +HTTP functions without rate limiting (DDoS = cost spike); over-allocated memory; +recursive trigger patterns (function writes to the collection that triggers it); +unnecessary reads before writes. + +**Storage**: no upload size limits (client AND server); missing file cleanup on +deletion; missing App Check; missing CDN cache headers; missing lifecycle rules. + +**Indexes & connections**: missing composite indexes (full scans); over-indexing +high-write fields; listeners not cleaned up on unmount; multiple app instances; +unbatched bulk writes. + +**Estimation**: flag unbounded queries that could read entire collections, +single user actions that fan out into N operations, and projected storage growth +without cleanup policies. Recommend budget alerts and spending limits. + +## Platform-Specific Surfaces + +**macOS**: App Sandbox escapes, Keychain access patterns, TCC permission abuse, +plist exposure, XPC vulnerabilities, Gatekeeper bypass, world-readable files. + +**iOS**: insecure URL schemes, Keychain exposure, TLS validation bypass, +UserDefaults storing secrets, ATS disabled, screenshot/cache exposure, insecure +WKWebView configuration. + +**Linux**: SUID/SGID binaries, cron injection, insecure systemd units, sudoers +misconfigurations, exposed Unix sockets, container escape vectors, insecure +mounts. + +**Windows**: registry exposure of secrets, UAC bypass, insecure COM objects, +DLL hijacking, named pipe ACLs, service privilege escalation, insecure file +ACLs, token impersonation. + +**Cross-platform**: path traversal, symlink attacks, environment variable +injection, predictable temp files, TOCTOU races, buffer overflows in native +code, unprotected IPC, plaintext credential storage. + +## .NET / ASP.NET + +- Missing `[Authorize]` attributes; CORS `AllowAnyOrigin` in production +- Missing anti-forgery tokens; insecure cookie configuration +- Secrets in `appsettings.json` without user-secrets/key vault +- `ASPNETCORE_ENVIRONMENT=Development` in production; missing HSTS +- EF Core: `FromSqlRaw` with interpolated input; unparameterized dynamic LINQ; + connection strings in plain text; N+1 lazy loading +- NuGet: untrusted sources, missing `nuget.config` restrictions, missing lock files +- Binary: BinaryFormatter/SoapFormatter deserialization, missing strong naming, + reflection-based type loading from untrusted input + +## Delphi / Lazarus / Free Pascal + +- Hardcoded credentials in `.dpr`/`.lpr`/`.pas`; plaintext connection strings + (dbExpress/FireDAC/SQLdb); Firebird/InterBase embedded passwords +- Missing parameterized queries (including `EXECUTE STATEMENT` in Firebird PSQL) +- Unencrypted `.fdb`/`.gdb`/SQLite files; missing TLS on Indy/Synapse sockets +- Unsafe pointer operations; missing `{$RANGECHECKS ON}`/`{$OVERFLOWCHECKS ON}`; + buffer issues in `Move`/`FillChar`/`GetMem` +- Insecure INI/registry storage of sensitive data + +## Go + +- SQL via `fmt.Sprintf` instead of parameterized queries +- `exec.Command` with unsanitized input; user-controlled paths in file reads +- `template.HTML` bypassing auto-escaping; `unsafe.Pointer`/CGo boundaries +- Goroutine leaks (missing context cancellation); data races on shared state +- CORS `AllowAllOrigins: true`; missing body size limits; missing rate limiting +- Modules: `replace` directives to untrusted sources; missing `go.sum`; + `govulncheck` findings + +## Installers, DLLs & Binaries + +- DLL hijacking/side-loading; missing ASLR/DEP flags; unsigned DLLs +- Installer custom actions with elevated privileges; unsigned installers; + insecure file permissions set at install; leftover sensitive files on uninstall +- Auto-update over HTTP or without signature verification; debug symbols/PDB in + release; missing compiler hardening flags (`/GS`, `/DYNAMICBASE`, `/NXCOMPAT`) + +## Logic & Business Flaws + +- Race conditions and TOCTOU; business logic bypass (payment/validation skips) +- Mass assignment from unfiltered user input +- Insecure deserialization (pickle, YAML, BinaryFormatter, unsafe JSON revivers) + +## Database Security (SQL / NoSQL) + +**Structure**: schema flaws enabling leakage; missing FK constraints; missing +audit columns; missing soft-delete for compliance data. + +**Queries**: dynamic SQL built by concatenation; injectable stored procedures; +`SELECT *` on sensitive tables; unbounded queries without LIMIT enabling +exfiltration. + +**Access**: app connections using DBA-privileged users; default credentials; +databases reachable from public networks; missing TLS; connection strings in +version control. + +**Per engine**: +- PostgreSQL: RLS policies, `pg_hba.conf`, superuser roles, `search_path` injection +- MySQL/MariaDB: GRANT scope, `LOAD DATA INFILE`, `secure-file-priv`, binlog exposure +- SQL Server: `xp_cmdshell`, `TRUSTWORTHY` databases, dynamic SQL in procedures +- Firebird: SYSDBA default password, UDF library security +- SQLite: file permissions, encryption at rest, journal mode +- Oracle: TNS listener security, default accounts, PL/SQL privilege escalation +- MongoDB: auth disabled, `0.0.0.0` bind, operator injection, missing schema validation +- Redis: no `requirepass`, dangerous commands enabled (FLUSHALL/CONFIG/EVAL), no TLS +- CouchDB: admin party mode, permissive `_security`, exposed admin panel +- DynamoDB: over-permissive IAM, missing encryption at rest, unbounded scans +- Cassandra: AllowAllAuthenticator, missing encryption, broad grants diff --git a/csreview/reference/subagents.md b/csreview/reference/subagents.md new file mode 100644 index 0000000..e24a40e --- /dev/null +++ b/csreview/reference/subagents.md @@ -0,0 +1,66 @@ +# CSReview Reference - Subagent Orchestration Protocol + +Detailed protocol for the scatter-gather workflow summarized in SKILL.md. Use it +only when the agent runtime supports subagents AND the workspace is large +enough to justify the extra token/runtime cost; otherwise run sequentially. + +## Dependency graph + +1. **Phase 0 + Phase 1 sequential gate** — detect tools, run the + engine-orchestrated SAST/SCA once (the `csreview` CLI does this), and build + the shared project map (techStack, frameworks, package managers, BaaS files, + IaC files, routes, cached tool JSON). +2. **Compatibility-gated fan-out** — spawn only subagents matching the map: no + Delphi subagent without Pascal files, no Firebase subagent without Firebase + rules/config, no Go subagent without Go modules. +3. **Parallel validation** — subagents validate candidate findings in their + domain from the shared map, local files, and cached tool output. They never + rerun whole-tree scanners. +4. **Gather barrier** — wait for all subagents before correlation. +5. **Reduce** — one coordinator merges partials, then runs + `dedup -> ASVS -> compliance -> score -> report` in that order. +6. **Single writer** — subagents write only partial JSON to + `csreview-reports/.partials/.json`; the coordinator (in practice: + the engine CLI re-run after partials exist) is the only writer of the final + reports. + +## Partial file contract + +Every partial finding uses the canonical finding schema and sets +`source: "subagent:"` (e.g. `subagent:auth`): + +```json +{ + "severity": "HIGH", + "category": "Authentication", + "name": "JWT signature not verified", + "description": "...", + "file": "src/middleware/auth.ts", + "line": 42, + "vulnerableCode": "...", + "cwe": "CWE-347", + "owasp": "A07:2021", + "fix": "...", + "confidence": "MEDIUM", + "exploitation": "...", + "references": ["https://..."], + "source": "subagent:auth" +} +``` + +Required fields (validated by the engine): `severity`, `category`, `name`, +`description`, `file`, `line`, `cwe`, `fix`, `confidence`, `source`. Optional +partial metadata may list `toolExecutions` so the coordinator can verify +whole-tree tools ran only once. + +## Engine enforcement + +When `csreview-reports/.partials/` exists, the engine reads the partial JSON, +validates the schema, merges valid `subagent:*` findings into the final set +(deduplicating against `csreview-detector`, `semgrep`, `npm-audit`, +`osv-scanner`, and the provisioned tools — matching `file:line:CWE` evidence is +promoted to `CONFIRMED`), and exposes `partialReconciliation` in its result. +`--strict-partials` (CLI) or `reconcilePartials(outputDir, findings, { strict: +true })` makes the run fail when the Definition of Done does not reconcile: +final subagent finding count must equal the deduplicated partial count, and no +whole-tree tool may appear executed more than once in partial metadata. diff --git a/csreview/reference/tooling.md b/csreview/reference/tooling.md new file mode 100644 index 0000000..e43cbbf --- /dev/null +++ b/csreview/reference/tooling.md @@ -0,0 +1,89 @@ +# CSReview Reference - External Tool Detection, Invocation & Installation + +The engine orchestrates Semgrep, the lockfile-selected Node package audit, and +OSV-Scanner deterministically (plus Gitleaks/Trivy/gosec/Bandit under +`--provision-tools`). Everything else here is **agent-recommended**: run a tool +only if it is already available or the user opted into provisioning, report its +results as supplemental evidence, and never install tools into the analyzed +project. + +## Detection commands + +```bash +semgrep --version # MANDATORY baseline attempt +osv-scanner --version +npm --version # npm audit (npm lockfiles) +pnpm --version # pnpm audit (pnpm-lock.yaml) +bun --version # bun audit (bun.lock / bun.lockb) +yarn --version # yarn audit (agent-recommended; not engine-parsed) +bandit --version # Python AST security +trivy --version # vulns + misconfig + secrets (fs scan) +gosec --version # Go security +gitleaks version # secrets (provisionable) +codeql version +npx eslint --version +snyk --version +safety --version +grype version +hadolint --version +tflint --version +checkov --version +brakeman --version +retire --version +pip-audit --version +cargo audit --version +dotnet --version # dotnet list package --vulnerable +govulncheck -version +``` + +## Per-tool invocation (read-only forms) + +```bash +# Semgrep — registry rules (default; requires network) or local rules +semgrep --config auto --json --quiet +semgrep --config p/security-audit --config p/secrets --config p/owasp-top-ten --json +# The engine accepts --semgrep-config to replace "auto" (adds --metrics=off). + +# Dependency SCA +osv-scanner scan --format json +npm audit --json +pnpm audit --json +bun audit --json +dotnet list package --vulnerable --include-transitive +cargo audit --json +pip-audit --format json --desc + +# Stack-native SAST / config scanners +bandit -r -f json -ll -i --skip B101 +trivy fs --format json --scanners vuln,misconfig,secret +gosec -fmt json -out /gosec-report.json -severity medium ./... +checkov -d -o json --quiet --compact +hadolint /Dockerfile --format json +snyk test --json --severity-threshold=medium +``` + +Never run fix/update/remediation subcommands (e.g. `osv-scanner fix`, +`npm audit fix`) during a CSReview run — the scan is read-only. + +## Installation pointers (for "missing recommended tool" entries) + +```bash +pipx install semgrep # or: uv tool install semgrep / brew install semgrep +winget install Google.OSVScanner # or: brew install osv-scanner +pip install bandit +pip install pip-audit +pip install checkov +cargo install cargo-audit +go install github.com/securego/gosec/v2/cmd/gosec@latest +go install golang.org/x/vuln/cmd/govulncheck@latest +npm install -g snyk +choco install trivy # or: scoop install trivy / brew install trivy +choco install hadolint # or: brew install hadolint +npm install --save-dev eslint-plugin-security eslint-plugin-no-unsanitized +``` + +With `--provision-tools`, the engine downloads Gitleaks, Trivy, and gosec from +their official GitHub releases, verifies the published SHA-256 checksums before +anything is made executable, and runs them from an isolated, gitignored +`.csreview/bin/` — never globally, never as project dependencies. Bandit is +PyPI-distributed and is only used when already installed. diff --git a/csreview/test/analysis.test.js b/csreview/test/analysis.test.js index 5333908..062a805 100644 --- a/csreview/test/analysis.test.js +++ b/csreview/test/analysis.test.js @@ -26,6 +26,20 @@ function makeTempProject() { return fs.mkdtempSync(path.join(os.tmpdir(), 'csreview-test-')); } +// The documentation set under contract: the GitHub landing README, the +// canonical SKILL.md, and the on-demand reference/*.md files SKILL.md links to. +// Doc-honesty tests assert against the whole set so content can move between +// the lean instruction core and the reference files without losing a contract. +function readDocs() { + const referenceDir = 'reference'; + const referenceDocs = fs + .readdirSync(referenceDir) + .filter((name) => name.endsWith('.md')) + .sort() + .map((name) => fs.readFileSync(path.join(referenceDir, name), 'utf8')); + return [fs.readFileSync('../README.md', 'utf8'), fs.readFileSync('SKILL.md', 'utf8'), ...referenceDocs].join('\n'); +} + function writeFile(root, relativePath, content) { const target = path.join(root, relativePath); fs.mkdirSync(path.dirname(target), { recursive: true }); @@ -707,7 +721,7 @@ test('skill requires external research when framework or security context is unc }); test('skill recommends stack-native read-only lint and scanner tools', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Stack-Native Tool Recommendation Matrix/i); assert.match(docs, /do not install.*analyzed project/i); @@ -724,7 +738,7 @@ test('skill recommends stack-native read-only lint and scanner tools', () => { }); test('skill permits only explicit complementary local DAST after remediation', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Phase 9: Optional Local DAST Complementary Report/i); assert.match(docs, /after the user or coding agent has implemented/i); @@ -741,7 +755,7 @@ test('skill permits only explicit complementary local DAST after remediation', ( }); test('documentation separates engine-orchestrated tools from agent-recommended tools honestly', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Engine-Orchestrated Tools/i); assert.match(docs, /Semgrep[\s\S]*npm audit[\s\S]*OSV-Scanner/i); @@ -752,7 +766,7 @@ test('documentation separates engine-orchestrated tools from agent-recommended t }); test('documentation describes vibe coding as heuristics rather than deterministic authorship scoring', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Vibe Coding Heuristics/i); assert.match(docs, /does not prove AI authorship/i); @@ -761,7 +775,7 @@ test('documentation describes vibe coding as heuristics rather than deterministi }); test('skill defines compatible scatter-gather security subagent orchestration', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Scatter-Gather Security Subagent Orchestration/i); assert.match(docs, /Phase 0[\s\S]*Phase 1[\s\S]*sequential gate/i); @@ -775,7 +789,7 @@ test('skill defines compatible scatter-gather security subagent orchestration', }); test('skill defines subagent orchestration DoD and non-negotiable rules', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Subagent Orchestration DoD/i); assert.match(docs, /csreview-reports\/\.partials\/\.json/); @@ -810,7 +824,7 @@ test('README exposes the canonical SKILL.md for GitHub landing review', () => { }); test('documentation aligns report handoff names and avoids exact patch instructions', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.doesNotMatch(docs, /Apply the corrected code exactly as shown/i); assert.doesNotMatch(docs, /@csreview review security-findings\.md/i); @@ -821,7 +835,7 @@ test('documentation aligns report handoff names and avoids exact patch instructi }); test('documentation requires global skill installation by default', () => { - const docs = `${fs.readFileSync('../README.md', 'utf8')}\n${fs.readFileSync('SKILL.md', 'utf8')}`; + const docs = readDocs(); assert.match(docs, /Global Skill Installation/); assert.match(docs, /global agent skill/i); From 045a8e87c96637f725472c5dda63ca112cbc1552 Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 10 Jun 2026 15:03:50 -0300 Subject: [PATCH 4/6] chore: bump version to 0.1.4 Co-Authored-By: Claude Fable 5 --- csreview/package-lock.json | 4 ++-- csreview/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/csreview/package-lock.json b/csreview/package-lock.json index 4e610a5..cae5c10 100644 --- a/csreview/package-lock.json +++ b/csreview/package-lock.json @@ -1,12 +1,12 @@ { "name": "csreview", - "version": "0.1.3", + "version": "0.1.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "csreview", - "version": "0.1.3", + "version": "0.1.4", "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/csreview/package.json b/csreview/package.json index 7b4d9a9..f3d903c 100644 --- a/csreview/package.json +++ b/csreview/package.json @@ -1,6 +1,6 @@ { "name": "csreview", - "version": "0.1.3", + "version": "0.1.4", "description": "Development-time local workspace security alignment for AI coding agents", "main": "src/index.js", "bin": { From 7fd2bde7819240f1025b53a31ff805643514e0fc Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 10 Jun 2026 15:09:04 -0300 Subject: [PATCH 5/6] test: assert package version shape instead of a pinned number The exact-version pin broke CI on every release bump (this PR's bump to 0.1.4 included) without protecting anything; the semver-shape assertion keeps the metadata contract. Co-Authored-By: Claude Fable 5 --- csreview/test/analysis.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csreview/test/analysis.test.js b/csreview/test/analysis.test.js index 062a805..462307c 100644 --- a/csreview/test/analysis.test.js +++ b/csreview/test/analysis.test.js @@ -693,7 +693,9 @@ test('package metadata declares Semgrep as a required external tool', () => { const osvScanner = recommendedTools.find((tool) => tool.name === 'osv-scanner'); const pnpmAudit = recommendedTools.find((tool) => tool.name === 'pnpm audit'); - assert.equal(pkg.version, '0.1.3'); + // Shape, not a pinned number: pinning the exact version forced editing this + // test on every release bump without protecting anything. + assert.match(pkg.version, /^\d+\.\d+\.\d+$/); assert.match(pkg.description, /development-time local workspace security alignment/i); assert.ok(pkg.keywords.includes('ai-agent-skill')); assert.ok(pkg.keywords.includes('semgrep')); From 577de38d8a92f7960784403510a3a4e4e975056e Mon Sep 17 00:00:00 2001 From: dev-ecd-dm Date: Wed, 10 Jun 2026 15:27:30 -0300 Subject: [PATCH 6/6] chore(ci): dogfood self-scan job gated with --fail-on high MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Runs CSReview against its own repository on every PR (Semgrep installed, update check skipped) and fails the build when HIGH/CRITICAL findings remain — exercising the new CI gate end to end. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73ef1bc..db8e3ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,3 +57,29 @@ jobs: - name: Verify package contents run: npm pack --dry-run + + self-scan: + name: Self-scan (dogfood, --fail-on high) + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: 24 + cache: npm + cache-dependency-path: csreview/package-lock.json + + - name: Install dependencies + run: npm ci + working-directory: csreview + + - name: Install Semgrep + run: python -m pip install --upgrade semgrep + + - name: Run CSReview against its own repository + run: node csreview/src/cli.js . --agent-name ci --no-update-check --fail-on high