Skip to content

coordination: oncofiles v5.15 security sweep — query_db allowlist tightening (retest required) #437

Description

@peter-fusek

What

Oncofiles is shipping a P0 security sweep (oncofiles#484) to close cross-patient data leaks reported by Michal Gašparík.

Phase 2 of that sweep tightens the query_db MCP tool that Oncoteam uses for lab-trend audits and clinical analyses. Some of your existing queries will break — intentionally — after the change.

What's changing (Phase 2)

  • query_db moves from block-list (only a handful of credential tables denied) to allow-list (every other table denied by default).
  • patient_id filter check moves from regex to SQL AST parse (sqlglot) — requires literal equality patient_id = '<uuid>' on every patient-scoped table reference. These will no longer satisfy the filter:
    • GROUP BY patient_id
    • WHERE patient_id LIKE '%'
    • WHERE patient_id IS NOT NULL
    • WHERE patient_id IN (...)
    • Missing pid filter + admin session (no more implicit "admin = see everything")
  • The patient_slug= argument becomes mandatory for patient-scoped queries — no more silent fallback to the caller's resolved pid when the query doesn't specify a patient.
  • sqlite_master, pragma_*, patients, newsletter_subscribers, email_entries, calendar_entries, clinical_records, clinical_analyses, sync_history are all denied at the allow-list layer.

Action required on Oncoteam side

  1. Inventory every query_db call in this repo.
  2. For each:
    • Confirm it targets a table in the new allow-list: documents, activity_log, conversations, treatment_events, research_entries, lab_values, document_pages, agent_state, patient_context, conversation_entries, clinical_records (if added), prompt_log, schema_migrations, sync_history (if added), document_cross_references.
    • Rewrite filter to WHERE patient_id = '<uuid>' literal equality (or = :pid bind).
    • Add explicit patient_slug= argument.
  3. Retest via the Oncoteam agent after oncofiles v5.15.0 ships (ETA 2026-04-27).
  4. Any table you need that's not on the allow-list → comment here and we'll evaluate adding it.

Why

From oncofiles's empirical retest — our own probes:

  • SELECT * FROM patients → returned full roster with caregiver_email + diagnosis_summary (this is what Michal screenshotted)
  • WHERE patient_id LIKE '%' on documents → returned every doc, every patient (296 rows)
  • GROUP BY patient_id on activity_log → returned 36,155 rows across 2 patients

Medical data; EU AI Act HIGH RISK; this is not optional.

Timeline

  • oncofiles Phase 2 lands 2026-04-25
  • oncofiles v5.15.0 tag 2026-04-27
  • Oncoteam self-retest by 2026-04-28

Related

  • oncofiles#484 (meta)
  • oncofiles#483 (Michal's original report)
  • prior coordination: oncoteam#433 (patient_slug propagation), oncoteam#406 (agent_state)

cc @peter-fusek

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions