Skip to content

fix: critical bug fixes from codebase audit#352

Closed
code-by-mahereddy wants to merge 1 commit into
DeusData:mainfrom
code-by-mahereddy:fix/audit-critical-bugs
Closed

fix: critical bug fixes from codebase audit#352
code-by-mahereddy wants to merge 1 commit into
DeusData:mainfrom
code-by-mahereddy:fix/audit-critical-bugs

Conversation

@code-by-mahereddy
Copy link
Copy Markdown

Bug Fixes from Codebase Audit

Critical

  • LIKE pattern bug (store.c): Double-percent format string produced wrong SQL LIKE pattern, making find_edges_by_url_path always fail
  • Use-after-free (store.c): like_pool_add could free pointer, but subsequent code still used it
  • Memory leak (cypher.c): expr_free silently dropped subtrees when 128-entry stack overflowed

High

  • Path traversal (store.c, mcp.c, http_server.c): Project names were not validated before interpolation into file paths
  • JSON-RPC 2.0 violation (mcp.c): Response missing both result and error keys when both were NULL
  • Buffer overflow (mcp.c): collect_db_project_names offset could exceed buffer size on truncation
  • XSS (http_server.c): Directory names injected raw into JSON without escaping
  • NULL checks (store.c): Missing NULL guards on cbm_store_checkpoint, cbm_store_node_degree, cbm_store_restore_from

New utility

  • cbm_validate_project_name() in str_util.c/h — validates project names are safe for file path construction

All fixes verified with successful build (make -f Makefile.cbm cbm with -Werror).

DeusData pushed a commit that referenced this pull request May 30, 2026
- str_util: add cbm_validate_project_name() — strict allowlist
  ([A-Za-z0-9._-], no leading dot, no '..', no path separators) so a
  project name can never escape the cache directory.
- store/mcp/http_server: validate project names (fail-closed) before
  interpolating them into .db file paths (path-traversal hardening;
  defense-in-depth for the wrong-path class in #331).
- store: fix use-after-free in the LIKE pool — like_pool_add() frees its
  argument when the pool is full, so capture pool_was_full before the add
  and skip the subsequent bind that would touch the freed pointer (two
  call sites). Also fix the find_edges_by_url_path LIKE pattern (stray
  double-percent) and add NULL guards to cbm_store_checkpoint /
  cbm_store_node_degree / cbm_store_restore_from.
- mcp: emit "result": null when a JSON-RPC response would otherwise
  carry neither result nor error (2.0 compliance); bounds-check the
  project-name accumulator against truncation.
- http_server: JSON-escape directory and parent names in the browse
  endpoint to prevent stored-XSS/JSON injection via crafted names.
- cypher: expr_free now recurses on EXPR_FREE_STACK overflow instead of
  silently dropping subtrees (memory leak).

Distilled from #352 onto current main (store.c like-pool hunk re-resolved
against the v0.7.0 search refactor; restored cypher.c EOF newline).
@DeusData
Copy link
Copy Markdown
Owner

Thank you, @code-by-mahereddy! 🙏 I gave this a careful line-by-line security review (it touches several sensitive files, so I wanted to be thorough) and every change held up — these are real, well-targeted fixes:

  • cbm_validate_project_name() is a proper allowlist (rejects .., path separators, leading dot, anything outside [A-Za-z0-9._-]) with no bypass — good path-traversal hardening, and I confirmed it doesn't reject any legitimate existing project names (full suite still green).
  • The like_pool use-after-free is genuine: like_pool_add() free()s its argument when the pool is full, so the subsequent where_bind_text(…, lp) was touching freed memory. Capturing pool_was_full and skipping the bind is exactly right.
  • JSON-RPC result: null for the both-NULL case, the browse-endpoint JSON-escaping (stored-XSS prevention), the expr_free leak fix, and the NULL guards all check out.

The PR branch had diverged from main (the store.c like-pool area was refactored in the v0.7.0 search work, and there was a stray EOF newline change in cypher.c), so rather than ask you to rebase six files I distilled your fixes onto current main and credited you as the commit author:

Landed in 21c73b5. Verified locally: build clean, all 3,617 tests pass including the validation-path tests. This strengthens the security posture tracked in #397 and adds defense-in-depth for #331. Genuinely excellent audit work — thank you! 🙏

@DeusData DeusData closed this May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants