217 Commits
Author SHA1 Message Date
Martin Vogel da7e77580f Fix Windows build: guard POSIX-only tests with #ifndef _WIN32
Path containment tests use realpath() and mkdir(path, mode) which are
not available on Windows. Shell-free exec tests already guarded.
v0.5.5
2026-03-21 23:19:50 +01:00
Martin Vogel 0888726073 Add security defense tests + eliminate system() command injection
TDD: 31 security tests covering shell injection prevention, SQLite
authorizer (ATTACH/DETACH blocked), SQL injection via Cypher, path
containment, and shell-free subprocess execution.

- Add cbm_exec_no_shell() in compat_fs: fork+execvp (POSIX), _spawnvp
  (Windows) — executes commands without shell interpretation
- Replace system() with cbm_exec_no_shell() for unzip extraction and
  version verification in update command — eliminates CodeQL
  command-line-injection alerts
- CodeQL: switch to build-mode manual for 100% source file coverage
- CodeQL gate: fix race condition between scan completion and alert API
  propagation (60s settle + double-check polling)
- Dismiss TOCTOU in pass_envscan.c (benign read-only directory walk)
2026-03-21 23:02:34 +01:00
Martin Vogel aa2b60be7d Fix 29 CodeQL alerts: command injection, snprintf overflow, TOCTOU races
- Command injection (CRITICAL): validate shell args before system() in
  update command's unzip and version-check calls
- TOCTOU cli.c: use open(O_CREAT, 0755) + fdopen() to set permissions
  atomically instead of fopen() + chmod() after close
- TOCTOU pass_envscan.c: open file first, then fstat() on fd to check
  size, eliminating stat-then-open race window
- Overflowing snprintf (11 locations): clamp offset after each append
  to prevent unsigned underflow on truncation in cypher.c, store.c,
  http_server.c, test_c_lsp.c
- Add CBM_SNPRINTF_APPEND macro in str_util.h for future safe appends
- CodeQL: remove pull_request trigger (only scan push to main)
- CodeQL gate: increase timeout from 30 to 45 minutes
- Add fuzz testing script (random JSON-RPC + Cypher mutations)
- 12 Scorecard governance alerts dismissed (not code vulnerabilities)
2026-03-21 22:18:31 +01:00
Martin Vogel 4322116349 CodeQL gate: wait for scan on current commit (max 30 min) 2026-03-21 20:51:35 +01:00
Martin Vogel f3e4eeafb1 Add CodeQL SAST + Scorecard + badges + LICENSE in archives 2026-03-21 20:44:31 +01:00
Martin Vogel 6bc40c42e3 Include LICENSE file in all release archives 2026-03-21 20:23:42 +01:00
Martin Vogel 785748cbdb Add OpenSSF Scorecard workflow (weekly + push to main) 2026-03-21 20:14:55 +01:00
Martin Vogel 6e0ad6bc61 Scorecard: threshold gate (>=4.0) instead of inline report 2026-03-21 20:11:02 +01:00
Martin Vogel d974b50304 VirusTotal: scan extracted binaries, not archives
Archives >3MB may not be unpacked by VirusTotal, meaning only the
container gets scanned (meaningless). Now extracts the actual
executables from tar.gz/zip before uploading to VirusTotal.
Users still download archives (preserves Unix permissions).
Also fixes analysis ID parsing (base64 format, not SHA256).
Also fixes SBOM format (SPDX 2.3 instead of CycloneDX).
2026-03-21 18:48:51 +01:00
Martin Vogel 88f8908c41 Fix VirusTotal: use /analyses/ endpoint with base64 analysis ID 2026-03-21 18:44:37 +01:00
Martin Vogel 1d0889e5f9 Fix SBOM: use SPDX 2.3 format (CycloneDX failed schema validation) 2026-03-21 18:15:42 +01:00
Martin Vogel b6c32a4f13 Skip SBOM attestation (schema validation fails), keep as release asset 2026-03-21 18:10:55 +01:00
Martin Vogel 77b9e7def7 Fix SBOM: use python3 for valid JSON (heredoc indentation broke format) 2026-03-21 17:46:08 +01:00
Martin Vogel e2b7797d47 Fix ClamAV macOS: suppress X509 SSL errors in freshclam 2026-03-21 17:18:35 +01:00
Martin Vogel dd30132e2d Pin Actions to SHA + enforce via security audit + Dependabot
- All GitHub Actions pinned to immutable commit SHAs (prevents
  tag-poisoning attacks like tj-actions/changed-files incident)
- Security audit (Layer 1) now blocks unpinned Actions in CI
- Dependabot configured to auto-propose SHA updates weekly
- Pre-commit hooks tracked in scripts/hooks/ for contributors
- Time-bomb detection + MCP file read audit added to Layer 1
2026-03-21 16:57:17 +01:00
Martin Vogel c371e9f07d Add time-bomb + MCP file read audit, tracked pre-commit hooks
Security audit (Layer 1) new checks:
- Time-bomb scan: flags time()/sleep()/clock() near dangerous calls
- MCP file read audit: tracks fopen/fread count in mcp.c against
  expected max (detects data exfiltration through tool responses)

Pre-commit hooks now tracked in scripts/hooks/:
- Contributors activate with: git config core.hooksPath scripts/hooks
- Runs: lint → security audit → build + test
- setup.sh already configures this automatically
2026-03-21 16:43:48 +01:00
Martin Vogel e0bce845eb Fix SBOM: valid JSON format for attest-sbom action 2026-03-21 16:34:03 +01:00
Martin Vogel 6881812b48 VirusTotal gate: wait for 100% scan completion, no compromises
- Wait until at least 60 engines have actually scanned (not just
  reported type-unsupported/failure/timeout)
- 20 minute timeout per binary (was 5 minutes)
- If scan doesn't complete in time → FAIL (incomplete scan is not clean)
- Engines that can't scan (type-unsupported, failure, timeout) are
  excluded from the completion count
2026-03-21 16:10:54 +01:00
Martin Vogel b5490cf9b9 Clarify native AV scans passed in release notes 2026-03-21 15:51:00 +01:00
Martin Vogel e5b6ee5733 Fix ClamAV freshclam config: ensure signatures are downloaded
freshclam requires DatabaseMirror set in config. Without it, ClamAV
scans with empty signatures (catches nothing). Now properly configures
freshclam.conf on both Linux (apt) and macOS (Homebrew) before updating.
2026-03-21 15:45:54 +01:00
Martin Vogel f8862144bf Add native AV scans on all 3 platforms + update SECURITY.md
Every platform now has a real antivirus gate that fails the build:
- Windows: Windows Defender with ML heuristics (MpCmdRun.exe)
- Linux: ClamAV with freshclam signature update
- macOS: ClamAV with freshclam signature update

Any detection on any platform blocks the release-draft from being
created. This is on top of the VirusTotal zero-tolerance gate in
the verify job.

SECURITY.md updated with complete security architecture.
2026-03-21 15:39:45 +01:00
Martin Vogel 75b5dcb897 Fix VirusTotal output parsing + use file report API
- Output is comma-separated, not newline — use tr ',' '\n' to split
- URLs are /gui/file/<sha256> permalinks — extract SHA256 hash and
  query /api/v3/files/<sha256> for last_analysis_stats
- Release notes table builder uses same comma-split fix
- Gate uses /tmp flag file to propagate failure from subshell
2026-03-21 15:22:11 +01:00
Martin Vogel 398ef68691 Add VirusTotal zero-tolerance gate: any detection blocks publish
The verify job polls VirusTotal API for completed scan results.
If ANY engine flags ANY binary as malicious or suspicious, the
release stays as draft and the pipeline fails. Zero tolerance —
investigate and fix before retrying.
2026-03-21 15:00:08 +01:00
Martin Vogel e1b106cb2b Release pipeline: draft → verify → publish flow
Restructured release to prevent unverified binaries from being public:
1. release-draft: create draft release (not visible to users)
2. verify: VirusTotal scan + OpenSSF Scorecard on draft binaries
3. If verification passes: append results to notes + publish
4. If verification fails: draft stays unpublished
2026-03-21 14:51:18 +01:00
Martin Vogel 2e21a0133b Release security hardening: VirusTotal + attestations + cosign + SBOM + OpenSSF + SECURITY.md
Release pipeline (step 5 + 6) now includes:
- SLSA build provenance attestations for all binaries
- Sigstore cosign keyless signing (.bundle files)
- SBOM (CycloneDX) with all vendored dependencies
- VirusTotal scan of all binaries (70+ engines)
- OpenSSF Scorecard (repo security health score)
- All results appended to release notes automatically

Also:
- SECURITY.md: vulnerability reporting + security measures
- Removed DLL API strings from test binary (issue #89)
2026-03-21 14:34:22 +01:00
Martin Vogel f43774f975 Add VirusTotal scanning to release pipeline + CHANGELOG.md
- VirusTotal: scans all release binaries (tar.gz + zip) via
  crazy-max/ghaction-virustotal after publishing. Scan result
  links are appended to the release notes automatically.
- CHANGELOG.md: local copy of all release notes so history
  is preserved in the repo, not just on GitHub.
2026-03-21 14:05:53 +01:00
Martin Vogel 281a7608d5 Remove DLL resolve tracking (Windows Defender false positive)
The DLL resolve feature (f92fd66) contained literal strings
GetProcAddress, dlsym, LoadLibrary that triggered Windows Defender
Wacatac.B!ml heuristic detection on the v0.5.4 binary. These are
the exact API names malware uses for dynamic API resolution.

Removed the feature entirely — it served a niche use case (C/C++
projects with dynamic DLL loading) and the false positive blocks
all Windows users from using the tool.

Fixes #89.
2026-03-21 13:47:10 +01:00
Martin Vogel 63e6141ac6 Add OpenClaw + VS Code agent detection (10 agents total)
- OpenClaw: detect ~/.openclaw/, write MCP config to openclaw.json
- VS Code was already wired in PR #79 but not counted in README
- Agent struct initializer uses memset instead of counting booleans
- README updated: 8 → 10 agents
2026-03-21 01:43:41 +01:00
Martin Vogel 8ca7199847 Add Content-Length framed transport support (OpenCode compatibility)
Some MCP clients (OpenCode, some VS Code extensions) use LSP-style
Content-Length framing instead of bare JSONL:

  Content-Length: 123\r\n\r\n{"jsonrpc":"2.0",...}

The server now auto-detects the transport: if a line starts with
"Content-Length:", it reads the header, skips the blank separator,
reads the exact payload, and responds with Content-Length framing.
Regular JSONL clients are unaffected — the detection only triggers
on the Content-Length prefix.

Fixes #78.
2026-03-20 21:22:06 +01:00
Martin Vogel f7315b9bc5 Robust UI audit: skip inline URL scan on dist/, keep structural checks
Minified JS in dist/ contains hundreds of string-constant URLs from
bundled npm libraries (React error pages, W3C namespace URIs, CDN
references, OSS credits) that are never fetched at runtime. Scanning
them produced an endless stream of false positives requiring per-URL
allowlisting.

Fix: split the A1 URL check by directory:
- src/ (our code): strict — any external URL is blocked
- dist/ (npm build output): skip inline URL scan entirely

Structural checks (A2-A6) still apply to dist/:
- External <script>/<link> loads in HTML
- Tracking/analytics identifiers
- Iframes, eval/Function, external WebSockets
2026-03-20 20:56:52 +01:00
Martin Vogel a9382ce110 Fix UI audit: allow truncated CDN URL in dist/ scan 2026-03-20 20:52:58 +01:00
Martin Vogel e09f27130e Fix Windows bulk test + dual MCP config location + CONTRIBUTING.md
- Bulk test: use cbm_tmpdir() instead of hardcoded /tmp/ (fixes
  Windows/MSYS2 where /tmp/ doesn't resolve for SQLite)
- Install: write MCP config to both ~/.claude/.mcp.json (Claude Code
  <=2.1.x) and ~/.claude.json (Claude Code >=2.1.80). Fixes #69.
- Uninstall: remove from both locations
- CONTRIBUTING.md: rewrite for pure C project (was still describing Go,
  causing contributors to submit Go PRs)
- Fix clang-format in mcp.c protocol version negotiation (PR #79 merge)
2026-03-20 20:32:38 +01:00
Martin Vogel de427776c0 Fix clang-format in merged PR #79 + update CONTRIBUTING.md
- Fix formatting in mcp.c protocol version negotiation (from PR #79 merge)
- Rewrite CONTRIBUTING.md for pure C project (was still describing Go,
  causing contributors to submit Go PRs that can't be merged)
2026-03-20 20:09:25 +01:00
Martin Vogel 92275ffa95 Merge PR #79: Fix VS Code compatibility (schema, install, protocol negotiation) 2026-03-20 19:52:59 +01:00
Martin Vogel b5b9c6bf78 Merge PR #72: keep WAL journal mode during bulk write 2026-03-20 19:29:40 +01:00
f92fd666b5 Port FastAPI Depends() + DLL resolve edge tracking (PR #66)
- FastAPI Depends(func_ref): scans Python function signatures for
  Depends() patterns and creates CALLS edges to the dependency function.
  Without this, auth/DI functions appear as dead code (in_degree=0).
- DLL resolve: scans C/C++ source for GetProcAddress/dlsym/Resolve
  patterns and creates CALLS edges to synthetic stub nodes, enabling
  call graph tracking across DLL boundaries.
- Extension scoping (#28) was already ported in 6a2b1f5.
- SQL size guard (#62) not needed: our C workers use 8MB stacks.

Tests: 3 new (httplink_laravel_path_filter, pipeline_fastapi_depends_edges,
pipeline_dll_resolve_edges). Total: 2041.

Co-Authored-By: kingchenc <kingchenc@users.noreply.github.com>
Co-Authored-By: mariomeyer <mariomeyer@users.noreply.github.com>
2026-03-20 19:19:12 +01:00
Martin Vogel 93d332d1e0 Fix security audit false positives in CI
- UI audit (L6): allowlist bundled framework URLs in dist/ (React error
  URLs, W3C namespace URIs, Three.js credits, Google Fonts, Tailwind).
  These are embedded by npm deps during Vite build, not our code.
- Binary strings (L2): skip URLs shorter than 15 chars — Windows binary
  has byte sequences that strings(1) interprets as "https://H9" etc.
- Allow Google Fonts <link> in HTML (loaded by index.html for Inter/
  JetBrains Mono fonts).
2026-03-20 18:47:55 +01:00
Martin Vogelandmariomeyer 6a2b1f547f Fix Laravel route false positives: extension scoping + path filter
Port of community fix (PR #65):
- Scope source-based route extractors by file extension: Go routes
  only on .go, Express on .js/.ts, Laravel on .php, Ktor on .kt/.kts.
  Prevents cross-framework false positives (e.g. Ktor regex matching
  PHP Cache::get calls).
- Filter Laravel route paths containing $ or : characters — these are
  cache keys or interpolated expressions, not URL paths. Laravel route
  parameters use {param} syntax, so valid routes are unaffected.

Co-Authored-By: mariomeyer <mariomeyer@users.noreply.github.com>
2026-03-20 18:42:44 +01:00
Martin Vogel f80d35094b Remove .mcp.json from repo (user-local config)
Was accidentally committed with a hardcoded absolute path.
The install command generates per-user MCP configs in the
correct editor-specific locations. Added to .gitignore.
2026-03-20 18:31:18 +01:00
Martin Vogel cd1417427c Add 8-layer security test suite + hardening
Code-level defenses:
- cbm_validate_shell_arg(): reject shell metacharacters before popen/system
- SQLite authorizer: block ATTACH/DETACH at engine level
- CORS localhost-only origin reflection (replaces wildcard *)
- Path containment: realpath() check in get_code_snippet
- process-kill restricted to server-spawned PIDs
- SHA256 checksum verification in update command

Security audit scripts (8 layers):
- L1: Static allow-list for dangerous calls + URLs
- L2: Binary string audit (URLs, payloads, credentials)
- L3: Network egress monitoring via strace (Linux)
- L4: Install output path + content validation
- L5: Smoke test hardening (clean shutdown, residual procs)
- L6: Graph UI audit (external domains, CORS, binding)
- L7: MCP robustness (23 adversarial JSON-RPC payloads)
- L8: Vendored integrity (checksums + dangerous call scan)

CI: parallel security-static job (no build needed), binary
layers in smoke jobs per-platform. Cleanup of test fixture
dirs in clean.sh + .gitignore.
2026-03-20 18:19:15 +01:00
Bing Ho 83619f8d41 Bump MCP protocol version with proper negotiation
Support protocol versions 2025-11-25, 2025-06-18, 2025-03-26, and
2024-11-05. The server now reads the client's requested version and
echoes it if supported, falling back to its latest otherwise. This
fixes the "unsupported protocol" warning in VS Code 1.112+ while
remaining backward-compatible with older clients.
2026-03-20 10:42:52 -05:00
Martin VogelandJay Sync c66d88745d Fix Swift call extraction: 0 CALLS edges (#43)
Swift tree-sitter grammar uses positional children (not named fields) for
call_expression, so extract_callee_name() returned NULL for every call.

- extract_calls.c: Swift-specific callee extraction via first named child
  for call_expression and constructor_expression nodes
- lang_specs.c: add constructor_expression to swift_call_types
- 4 new C tests: simple calls, method calls, constructors, chained calls

Co-Authored-By: Jay Sync <63868998+jay-sync@users.noreply.github.com>
2026-03-20 14:46:46 +01:00
Bing Ho 02575fb307 Add VS Code detection and MCP registration to install/uninstall
The install command detected many editors (Cursor, Zed, Gemini, etc.)
but not VS Code, even though cbm_install_vscode_mcp() already existed.
Add VS Code User config dir detection and wire it into both install
and uninstall flows, writing to ~/.config/Code/User/mcp.json (Linux)
or ~/Library/Application Support/Code/User/mcp.json (macOS).
2026-03-20 08:37:44 -05:00
Bing Ho 89970f2b3e Fix ingest_traces array schema missing items property
VS Code 1.112+ validates that all MCP tool array-type parameters
include an "items" definition (microsoft/vscode#248810). The
ingest_traces tool's "traces" parameter was missing this, causing
startup failures.
2026-03-20 08:31:06 -05:00
Martin Vogel f6b9b39c60 Fix snippet tests: align with simplified get_code_snippet handler
The snippet handler now uses exact QN + suffix matching only (no fuzzy/auto-resolve).
Updated 3 tests to match: fuzzy_suggestions, fuzzy_last_segment, auto_resolve_enabled.
v0.5.3
2026-03-20 13:45:17 +01:00
Martin Vogel d6a5f8984e Add incremental reindex + ADR hints in index/schema/adr responses
Incremental pipeline (pipeline_incremental.c):
- Disk-based delta re-indexing: classifies files by mtime+size vs stored
  hashes, deletes changed nodes (edges cascade), re-parses only changed
  files, merges into existing DB via cbm_gbuf_merge_into_store
- pipeline.c auto-routes: existing DB with hashes -> incremental, else full
- Full pipeline persists file hashes after dump for next incremental run
- No-op when nothing changed (watcher polls every 5-60s, 99% skip)
- 4 tests: noop, changed file, deleted file, new file added

ADR hints (ported from Go):
- index_repository: adr_present + adr_hint when no ADR exists
- get_graph_schema: adr_present + adr_hint per project
- manage_adr GET: adr_hint with creation instructions when no ADR
2026-03-20 13:15:01 +01:00
DeusData 54930c6544 README.md aktualisieren 2026-03-20 01:14:42 +01:00
Shane McCarronandClaude Sonnet 4.6 a0e809d425 fix(store): address QA round 2 findings
- Validate child exit status (WIFEXITED + WEXITSTATUS) after waitpid so
  the test fails fast if the child couldn't open the store, rather than
  passing vacuously due to the "crashed" row never being written

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:17:55 -05:00
Shane McCarronandClaude Sonnet 4.6 675fdf341e fix(store): address QA round 1 findings
- Wrap bulk_crash_recovery test and its POSIX includes with #ifndef _WIN32
  guards to fix compilation failure on Windows (fork/waitpid unavailable)
- Add negative assertion that the uncommitted "crashed" row is absent
  after crash recovery, completing the test's correctness verification

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:07:17 -05:00
Martin Vogel 78e1df2021 Refine messaging: seconds for avg repos, clarify AST (64 langs) vs LSP hybrid (Go/C/C++) 2026-03-19 23:44:35 +01:00