Commit Graph
20 Commits
Author SHA1 Message Date
c1154b6ed6 fix(security): header injection, link-prediction DoS, import ID sanitization (#912)
* fix(security): sanitize node_id in Content-Disposition to prevent header injection (CWE-113)

* fix(security): cap link prediction at 10k nodes with semaphore to prevent OOM DoS (CWE-770)

* fix(security): sanitize imported node IDs to prevent stored header injection chain (CWE-20)

* test(security): add self-contained PoC runner with real measured output

* test(security): add regression tests for header injection, DoS cap, import sanitization

* fix(security): comprehensive fix for header injection, DoS, and import ID sanitization

* fix: move semaphore to wrap entire data-load+scoring region, use node-specific edge queries (Qodo #2, #3)

* fix: sanitize edge source/target IDs to match sanitized node IDs (Qodo #4)

* fix: scope 999_999 check to predict_links function via AST (Qodo #1)

* fix: add explicit None guard to _sanitize_import_node_id

* fix(security): close import-sanitizer bypass, enforce link-prediction cap before the expensive scan

Follow-up to the fixes in this PR, found in review:

- export_import.py's "properties" in raw_node fast path stored the id
  verbatim, completely skipping _sanitize_import_node_id() -- a node
  payload of {"id": "<crlf>", "properties": {}} (the shape this app's
  own /api/export produces) bypassed the VULN-3 fix entirely. That
  branch now sanitizes id before storing.

- The link-prediction 10k-node cap checked `total` only after calling
  session.get_nodes()/get_edges(), which normalize the graph's entire
  matching set before applying `limit` -- so the DoS guard ran after
  the expensive work it exists to prevent had already happened, on
  every request regardless of graph size. Added
  GraphSession.get_raw_counts(), an O(1) check against the raw
  len(graph.nodes)/len(graph.edges), and moved the size check ahead of
  the normalizing calls (also added an edge-count cap).

- 5 of the existing regression tests asserted that literal words like
  "Set-Cookie"/"Content-Type" disappear from the sanitized value -- the
  sanitizer strips \r\n\x00"\ , not letters, so those assertions failed
  against this PR's own fix as submitted. Corrected to assert on the
  actual security property (no \r/\n survives), and added end-to-end
  tests that exercise the real /api/import -> /api/provenance/report
  route chain so the properties-key bypass has regression coverage.

Full explorer suite: 241 passed. tests/test_security_regression_pr2.py: 30 passed.

---------

Co-authored-by: Zohaib Hassnain <109234410+ZohaibHassan16@users.noreply.github.com>
Co-authored-by: Mohd Kaif <98801504+KaifAhmad1@users.noreply.github.com>
Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
2026-08-12 21:14:55 +05:30
Sunil 44f585ffce test(security): add regression tests for all security fixes 2026-08-11 15:17:23 +05:30
Sunil f5332589d5 fix(security): harden SPARQL read-only check against comment/prefix bypass 2026-08-11 15:17:21 +05:30
Sunil 9a21ca9834 fix(security): prevent Cypher injection via graph_name and dollar-delimiter breakout 2026-08-11 15:17:19 +05:30
Sunil a169cf3fb9 feat(security): wire API key auth middleware into Explorer app 2026-08-11 15:17:17 +05:30
Sunil 656baa7aee feat(security): add opt-in API key auth middleware for Explorer API 2026-08-11 15:17:15 +05:30
Sunil c94be3f9a6 fix(ontology): resolve relative redirects with urljoin, close resp on redirect 2026-08-11 15:01:34 +05:30
Sunil 142707db93 fix(sparql): wrap graph cap ValueError in SparqlResponse instead of 500 2026-08-11 15:01:31 +05:30
Sunil 3357c14ee3 fix(vector_store): use v.tolist() for numpy array serialization 2026-08-11 15:01:29 +05:30
Sunil 8fa2037619 fix: re-push vector_store.py with correct UTF-8 encoding 2026-08-10 22:28:48 +05:30
Sunil 5573ab7a9f fix: re-push ontology.py with correct UTF-8 encoding 2026-08-10 22:28:27 +05:30
Sunil 26f236923c fix: re-push pyproject.toml with correct UTF-8 encoding 2026-08-10 22:28:06 +05:30
Sunil c35899711d fix: re-push sparql.py with correct UTF-8 encoding 2026-08-10 22:27:45 +05:30
Sunil 0a113b9702 fix: make defusedxml required, fail closed if missing (reviewer feedback) 2026-08-10 22:26:49 +05:30
Sunil 2de6ff898a Merge branch 'main' into security/fix-critical-vulnerabilities 2026-08-10 22:01:52 +05:30
Sunil 22ea189d0b security: replace unsafe pickle with JSON in vector store (CWE-502) 2026-08-10 21:53:11 +05:30
Sunil 30d5fef180 security: fix SSRF via redirect bypass in ontology URL fetcher (CWE-918) 2026-08-10 21:52:47 +05:30
Sunil c85df419ae security: add defusedxml to explorer dependencies for XXE protection 2026-08-10 21:52:03 +05:30
Sunil 55f3ee6f84 security: fix SPARQL DoS via unbounded graph materialization (CWE-770) 2026-08-10 21:51:56 +05:30
Sunil 924765b042 security: fix XXE vulnerability in RDF/XML parser (CWE-611) 2026-08-10 21:51:27 +05:30