Skip to content

fix(holographic): sanitize FTS5 queries, fix entity wildcard matching, close DB on shutdown#6667

Open
aaronlab wants to merge 1 commit into
NousResearch:mainfrom
aaronlab:fix/holographic-fts5-injection-entity-wildcard-shutdown
Open

fix(holographic): sanitize FTS5 queries, fix entity wildcard matching, close DB on shutdown#6667
aaronlab wants to merge 1 commit into
NousResearch:mainfrom
aaronlab:fix/holographic-fts5-injection-entity-wildcard-shutdown

Conversation

@aaronlab

@aaronlab aaronlab commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • FTS5 injection: sanitize user queries passed to MATCH by wrapping tokens in double quotes
  • Entity wildcard: replace LIKE with = COLLATE NOCASE for entity name matching, and INSTR for alias matching
  • Shutdown leak: call store.close() before setting to None in plugin shutdown

Details

FTS5 query injection (HIGH)

search_facts() passes raw user input to WHERE facts_fts MATCH ?. FTS5's MATCH accepts a mini-language with operators (AND, OR, NOT, NEAR(), column filters like content:, prefix *). A query like NOT * crashes with a syntax error; tags:secret exfiltrates data across columns.

Fix: wrap each whitespace-delimited token in double quotes, stripping any embedded quotes first. This preserves word-level matching while neutralizing all FTS5 operators.

Entity name wildcard matching (HIGH)

_resolve_entity uses WHERE name LIKE ? for case-insensitive matching. But LIKE treats % and _ as wildcards. Entity name "100% Complete" matches "1000 Complete", "100X Complete", etc. — linking facts to wrong entities.

Fix: use WHERE name = ? COLLATE NOCASE for exact case-insensitive matching.

Alias wildcard matching (HIGH)

The alias search uses WHERE ',' || aliases || ',' LIKE '%,' || ? || ',%' — the user-supplied name is treated as a LIKE pattern. name = "%" matches every entity with any alias.

Fix: use INSTR(',' || LOWER(aliases) || ',', ',' || LOWER(?) || ',') > 0 for exact substring matching.

Shutdown resource leak (MEDIUM)

HolographicMemoryProvider.shutdown() sets self._store = None without closing the SQLite connection, leaking the connection and WAL file until GC.

Fix: call self._store.close() before nulling.

Test plan

  • Verify search_facts("NOT *") returns empty (not crash)
  • Verify entity "100% Complete" doesn't match "1000 Complete"
  • Verify alias search with % doesn't match all entities
  • Verify shutdown closes SQLite connection
  • Run pytest tests/ -q

🤖 Generated with Claude Code

…ies, close DB on shutdown

- store.search_facts: wrap FTS5 query tokens in double quotes to
  neutralize operators (AND, OR, NOT, NEAR, *, column filters) that
  could cause query injection, crashes, or cross-column exfiltration
- store._resolve_entity: replace LIKE with = COLLATE NOCASE for entity
  name matching — LIKE treats % and _ in entity names as wildcards,
  causing incorrect entity resolution (e.g., "100% Complete" matches
  "1000 Complete")
- store._resolve_entity: replace alias LIKE pattern with INSTR for
  exact substring matching — same wildcard bug in alias resolution
- __init__.shutdown: call store.close() before setting to None,
  preventing SQLite connection and WAL file leak on plugin shutdown

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@alt-glitch alt-glitch added type/security Security vulnerability or hardening comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers P2 Medium — degraded but workaround exists labels Apr 29, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #14262, #14033, #11333 — all fix holographic FTS5 sanitization. This PR adds entity wildcard and shutdown fixes beyond what the others cover.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #14262, #14033, #11333 — all fix holographic FTS5 sanitization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists tool/memory Memory tool and memory providers type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants