Skip to content

v0.6.5

Latest

Choose a tag to compare

@github-actions github-actions released this 11 Aug 17:19
· 1 commit to main since this release
5b31956

Release Date: August 11, 2026
Version: 0.6.5

Semantica 0.6.5 is a security release closing 6 externally-reported vulnerabilities across the Explorer API and the graph/triplet store backends — including a Critical missing-authentication gap and a Critical Cypher-injection path — plus a CodeQL-flagged ReDoS. It also ships an embedded Oxigraph TripletStore backend, full PROV-O trust/spec completeness for ProvenanceManager, the Altair Anzo triplet store backend, and closes out 25+ correctness bugs across vector stores, provenance, ontology validation, and the Explorer frontend.

Upgrading is strongly recommended for all deployments, especially anyone running the Explorer API.

What's Changed

Security

  • Missing authentication on all Explorer API routes (#909, GHSA-j4mq-hprp-987v, Critical) by @KaifAhmad1

    • Every route across all 11 API routers (graph, ontology, SPARQL, SHACL, provenance, temporal, analytics, import/export) was reachable with no credential — full read/write graph access and arbitrary SPARQL execution for anyone who could reach the port
    • New Depends(require_auth) validates X-API-Key against SEMANTICA_API_KEY; fails closed (503) when unset, rather than silently allowing anonymous access
    • SEMANTICA_ALLOW_ANONYMOUS=true remains available as an explicit opt-out for local/dev use
  • SSRF via redirect bypass in ontology URL fetching, plus DNS check-then-use hardening (#898, #916, GHSA-8c7v-62gr-hj6g, High) by @Sunil56224972 and @KaifAhmad1

    • A validated public first hop could redirect (302) to http://169.254.169.254/... (cloud instance metadata) or an internal service with no re-validation; redirects are now followed manually, capped at 5 hops, with every hop's target (including relative Location headers) re-validated
    • Follow-up (#916) closed a secondary DNS check-then-use (TOCTOU) window: the connection is now pinned directly to the validated IP via a custom requests adapter, with the real hostname still presented for the HTTP Host header and TLS SNI/certificate verification
    • Verified with real (non-mocked) local HTTP/HTTPS test servers, including a negative control confirming a hostname/cert mismatch is still rejected
  • Cypher injection via unvalidated node labels, relationship types, and property keys (#910, GHSA-482h-hw99-h62p, Critical) by @KaifAhmad1, review fix by @Sameer6305

    • Labels and property keys can't be parameterized like values; a document-derived entity type or property name could close the current Cypher token early and append arbitrary statements (e.g. DETACH DELETE) across the Neptune, Neo4j, and FalkorDB backends
    • New shared semantica/graph_store/query_sanitize.py validates every label/relationship-type/property-key interpolation site
  • SPARQL injection via unvalidated triplet IRIs (#911, #916, GHSA-8vgg-8mr4-r236, Critical) by @KaifAhmad1, review fix by @ZohaibHassan16

    • A subject/predicate/object containing > could close the <...> IRI token early and append arbitrary SPARQL (e.g. CLEAR ALL) across the Blazegraph, RDF4J, and Jena backends
    • Applied sparql_escaping.validate_uri() at every interpolation site; a follow-up (#916) closed a remaining gap where an already-<...>-wrapped object skipped validation
  • Missing Origin validation on the WebSocket handshake (#917, GHSA-4643-wpgq-w329, Moderate — anonymous-mode only) by @KaifAhmad1

    • CORSMiddleware doesn't cover WebSocket handshakes; under SEMANTICA_ALLOW_ANONYMOUS=true, /ws/graph-updates accepted a connection from any browser origin
    • Now checks Origin against the same allowlist CORSMiddleware already enforces for HTTP, before the key check
  • Polynomial-time ReDoS in the SPARQL route's _PREFIX_DECL regex (#915, CodeQL py/polynomial-redos) by @Sameer6305

    • Two overlapping quantifiers allowed O(n²) backtracking, reachable from req.query; fixed by making them character-disjoint, plus a 10,000-char defense-in-depth query length cap
  • 4 additional critical/high vulnerabilities in the Explorer API and vector store: RCE, XXE, DoS (#898) by @Sunil56224972

    • [CWE-502] Arbitrary code execution via pickle.load() in VectorStore.save()/load() — replaced with JSON; legacy .pkl files are now refused rather than deserialized
    • [CWE-611] XXE in the RDF/XML parser — defusedxml is now a declared dependency and _safe_parse_rdf() fails closed if it isn't importable
    • [CWE-770] DoS via unbounded SPARQL graph materialization — capped at 50,000 nodes/edges
    • Plus Cypher-injection hardening for Apache AGE's graph_name/$$-delimiter breakout, and comment/PREFIX-hiding bypass hardening for the read-only SPARQL keyword check
  • CI/CD supply-chain hardening against mutable-tag Action compromise (#824) by @KaifAhmad1

    • Every third-party GitHub Action across all 8 workflows pinned to a full commit SHA (closing the vector used against LiteLLM in March 2026); added a CI check that fails closed on any non-SHA uses: reference; added SLSA build provenance attestation and a protected pypi GitHub Environment
  • security-scan.yml's Safety dependency check was silently non-functional, pypdf2==3.0.1 removed (CVE-2023-36464), and 10 Bandit B324 false positives suppressed (#824) by @KaifAhmad1

  • SSRF protection for WebIngestor, SitemapCrawler, and RESTIngestor (#906, closes #867) by @pravit-amp

    • New shared validate_url_for_request() SSRF guard, wired into all three ingestors; allow_private_ips remains available as an explicit opt-in for trusted internal deployments

Added

  • Embedded Oxigraph backend for TripletStore (#838, closes #834) by @Linxiushen

    • In-process SPARQL 1.1 store via the optional pyoxigraph dependency — no external server (Blazegraph/Jena/RDF4J/Anzo) required
    • pip install "semantica[tripletstore-oxigraph]"; runs in memory by default or persists to a local directory
  • PROV-O trust blockers and general spec completeness for ProvenanceManager (#825) by @KaifAhmad1

    • Invalidation-instead-of-delete tombstoning, hash-chained integrity (verify_chain()), typed Agent/Activity records, downstream lineage traversal, W3C PROV-O qualified relations, bitemporal + Bundle support, and a configurable namespace
    • New CLI commands: semantica provenance invalidate|verify-chain|descendants
  • Altair Anzo triplet store backend (#813) by @KaifAhmad1 — a fourth peer to Blazegraph/RDF4J/Jena speaking plain SPARQL 1.1 over HTTP, no new dependency required

  • Comprehensive unit and security test suite for the /api/sparql Explorer route (#773) by @Sameer6305 — 34 new tests covering read-only allowlist enforcement, resource limiting, and RDF projection fidelity

  • Global default persistent storage for ProvenanceManager, plus a working provenance CLI (#795, #802) by @Sameer6305 and @KaifAhmad1 — every ingestion module now actually persists to the SQLite audit trail instead of silently falling back to in-memory storage

  • Markdown round-trip export/import for AgentMemory (#765, #786) by @SaurabhScripts and @Sameer6305 — human-editable, diff-friendly Markdown alternative to JSON serialization, with atomic upsert-by-ID import

Fixed

  • VectorStore.search_vectors() returned inconsistent result shapes across backend implementations (#853, closes #845) by @Sameer6305, reviewed by @KaifAhmad1
  • DecisionEmbeddingPipeline.find_similar_decisions() crashed for any VectorStore backend other than inmemory (#842, closes #839) by @Sameer6305
  • QdrantStore.search_vectors() returned results keyed by "payload" instead of "metadata" (#841, closes #840) by @divyankshah
  • Explorer Temporal panel never rendered after clicking the toolbar button (#830, #836) by @Sameer6305
  • HybridSearch.search() crashed for any VectorStore backend other than inmemory (#833, #837) by @KaifAhmad1
  • VectorStore.store_vectors() silently dropped metadata for FAISS (#832, #835) by @KaifAhmad1
  • AgnoDecisionKit.check_policy silently treated unevaluable policy rules as compliant (#778, #822) by @Sameer6305
  • No cycle detection for SKOS concepts at write time (#774, #819) by @mikemikimike, reviewed by @Sameer6305 and @KaifAhmad1
  • Agno _AgentScopedStore.upsert_memory silently swallowed decision recording failures (#779)
  • AgnoDecisionKit/AgnoKGToolkit silently swallowed Agno tool registration failures (#780, #818) by @Sameer6305 and @KaifAhmad1
  • ProvenanceManager tracking methods silently swallowed failures without logging (#783)
  • MCP handle_get_causal_chain returned an empty-but-valid response when unsupported (#781, #817) by @Sameer6305 and @KaifAhmad1
  • ProvenanceManager.track_entity persisted partial history on storage failure (#782, #816) by @Sameer6305 and @KaifAhmad1
  • ProvenanceManager duplicated checksum/persist/exception-swallow logic across 4 methods (#784, #815) by @Sameer6305 and @KaifAhmad1
  • SQLiteStorage/ProvenanceManager connection churn, non-atomic writes, batch tracking overhead (#807) by @Sameer6305
  • Closed remaining ProvenanceManager storage-failure test-coverage gaps (#785)
  • Explorer's Provenance UI used a naive 2-hop traversal instead of the audit-grade ProvenanceManager backend (#792, #809) by @Sameer6305
  • POST /shacl/validate and the /health SHACL dimension never ran live SHACL validation (#772, #804) by @Sameer6305 and @KaifAhmad1
  • Neptune cookbook CloudFormation stack exposed the database port to the entire internet (code scanning #26–28) by @KaifAhmad1
  • Knowledge-explorer Helm chart namespace/seccomp scanner findings reopened (code scanning #846–848, #68, #63) by @KaifAhmad1
  • react-hooks/set-state-in-effect cascading renders across 12 Explorer workspace files (#769, #796) by @Sameer6305 and @KaifAhmad1
  • Checkov flagged the knowledge-explorer Helm chart for the default Kubernetes namespace (code scanning #777–779) by @KaifAhmad1
  • No React error boundaries around lazy-loaded Explorer workspaces (#768, #794) by @Sameer6305
  • Explorer frontend workspaces silently swallowed network/server errors (#767, #790) by @Sameer6305
  • tests/explorer/test_explorer_api.py failed on current httpx (#788, #789) by @Sameer6305
  • Explorer backend routes returned HTTP 200 with error/empty bodies on failure (#770, #787) by @Sameer6305 and @KaifAhmad1

Testing

  • New test coverage for previously untested/lightly-covered split chunkers (SlidingWindow, Structural, Table, EntityAware, and KG chunkers) (#904, closes #864) by @pravit-amp
  • New test coverage for ClusterBuilder, MergeStrategyManager/PropertyMergeRule, and EntityMerger.merge_duplicates() in deduplication (#907, closes #866) by @pravit-amp

Contributors

@KaifAhmad1 · @Sameer6305 · @Sunil56224972 · @Linxiushen · @SaurabhScripts · @divyankshah · @mikemikimike · @pravit-amp · @ZohaibHassan16

Full Changelog: https://github.com/semantica-agi/semantica/blob/main/CHANGELOG.md