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)validatesX-API-KeyagainstSEMANTICA_API_KEY; fails closed (503) when unset, rather than silently allowing anonymous access SEMANTICA_ALLOW_ANONYMOUS=trueremains 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 relativeLocationheaders) 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
requestsadapter, with the real hostname still presented for the HTTPHostheader 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
- A validated public first hop could redirect (302) to
-
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.pyvalidates every label/relationship-type/property-key interpolation site
- 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.
-
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
- A subject/predicate/object containing
-
Missing Origin validation on the WebSocket handshake (#917, GHSA-4643-wpgq-w329, Moderate — anonymous-mode only) by @KaifAhmad1
CORSMiddlewaredoesn't cover WebSocket handshakes; underSEMANTICA_ALLOW_ANONYMOUS=true,/ws/graph-updatesaccepted a connection from any browser origin- Now checks
Originagainst the same allowlistCORSMiddlewarealready enforces for HTTP, before the key check
-
Polynomial-time ReDoS in the SPARQL route's
_PREFIX_DECLregex (#915, CodeQLpy/polynomial-redos) by @Sameer6305- Two overlapping quantifiers allowed O(n²) backtracking, reachable from
req.query; fixed by making them character-disjoint, plus a10,000-char defense-in-depth query length cap
- Two overlapping quantifiers allowed O(n²) backtracking, reachable from
-
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()inVectorStore.save()/load()— replaced with JSON; legacy.pklfiles are now refused rather than deserialized - [CWE-611] XXE in the RDF/XML parser —
defusedxmlis 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
- [CWE-502] Arbitrary code execution via
-
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 protectedpypiGitHub Environment
- 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
-
security-scan.yml's Safety dependency check was silently non-functional,pypdf2==3.0.1removed (CVE-2023-36464), and 10 Bandit B324 false positives suppressed (#824) by @KaifAhmad1 -
SSRF protection for
WebIngestor,SitemapCrawler, andRESTIngestor(#906, closes #867) by @pravit-amp- New shared
validate_url_for_request()SSRF guard, wired into all three ingestors;allow_private_ipsremains available as an explicit opt-in for trusted internal deployments
- New shared
Added
-
Embedded Oxigraph backend for
TripletStore(#838, closes #834) by @Linxiushen- In-process SPARQL 1.1 store via the optional
pyoxigraphdependency — no external server (Blazegraph/Jena/RDF4J/Anzo) required pip install "semantica[tripletstore-oxigraph]"; runs in memory by default or persists to a local directory
- In-process SPARQL 1.1 store via the optional
-
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
- Invalidation-instead-of-delete tombstoning, hash-chained integrity (
-
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/sparqlExplorer 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 workingprovenanceCLI (#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 @KaifAhmad1DecisionEmbeddingPipeline.find_similar_decisions()crashed for anyVectorStorebackend other thaninmemory(#842, closes #839) by @Sameer6305QdrantStore.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 anyVectorStorebackend other thaninmemory(#833, #837) by @KaifAhmad1VectorStore.store_vectors()silently dropped metadata for FAISS (#832, #835) by @KaifAhmad1AgnoDecisionKit.check_policysilently 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_memorysilently swallowed decision recording failures (#779) AgnoDecisionKit/AgnoKGToolkitsilently swallowed Agno tool registration failures (#780, #818) by @Sameer6305 and @KaifAhmad1ProvenanceManagertracking methods silently swallowed failures without logging (#783)- MCP
handle_get_causal_chainreturned an empty-but-valid response when unsupported (#781, #817) by @Sameer6305 and @KaifAhmad1 ProvenanceManager.track_entitypersisted partial history on storage failure (#782, #816) by @Sameer6305 and @KaifAhmad1ProvenanceManagerduplicated checksum/persist/exception-swallow logic across 4 methods (#784, #815) by @Sameer6305 and @KaifAhmad1SQLiteStorage/ProvenanceManagerconnection churn, non-atomic writes, batch tracking overhead (#807) by @Sameer6305- Closed remaining
ProvenanceManagerstorage-failure test-coverage gaps (#785) - Explorer's Provenance UI used a naive 2-hop traversal instead of the audit-grade
ProvenanceManagerbackend (#792, #809) by @Sameer6305 POST /shacl/validateand the/healthSHACL 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-effectcascading 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.pyfailed on currenthttpx(#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
splitchunkers (SlidingWindow,Structural,Table,EntityAware, and KG chunkers) (#904, closes #864) by @pravit-amp - New test coverage for
ClusterBuilder,MergeStrategyManager/PropertyMergeRule, andEntityMerger.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