| Version | Supported |
|---|---|
| 0.4.x | ✅ |
| < 0.4 | ❌ |
Always run the latest release. Security fixes land on the newest minor only.
Please report security issues privately — do not open a public issue.
- Open a GitHub private security advisory, or
- Email the maintainer (see the
authorsfield inpyproject.toml/ the GitHub profile).
Include: affected version, a reproduction, and the impact you observed. Expect an acknowledgement within a few days. Coordinated disclosure is appreciated.
This is a local stdio MCP server. It runs on the user's machine with the user's privileges and is driven by an LLM. The design assumptions:
- Tool arguments are LLM-generated and may be influenced by untrusted data. Datasets fetched from the portal can carry prompt-injection payloads. Any argument that reaches SQL or the filesystem is treated as hostile.
- No write path to the portal. Every portal-facing tool is read-only
(annotated
readOnlyHint: true). The only mutation is clearing the local Parquet cache (clear_cache, annotateddestructiveHint: true). - The portal API and resource files are external. Network-facing tools are
annotated
openWorldHint: true.
- Solr injection — every user value entering a CKAN
fqfilter passes through_escape_solr/_fq_term(ckan.py). - DuckDB identifier injection — all column identifiers go through
_quote_ident(analytics.py): an allowlist regex plus a denylist of comment/terminator substrings (--,/*,*/,;), then double-quoting. - Raw SQL (
query_resource) — two layers:_validate_sqlrejects anything that is not a single read-onlySELECT/WITH, and blocks DDL/DML keywords.- Sandbox: the resource is materialized into an in-memory table, then
enable_external_access=false+lock_configuration=trueare set before the user query runs. DuckDB table functions (read_text,read_csv,read_blob,glob, …) therefore cannot read local files or reach the network — closing the gap the keyword denylist alone would leave open.
- Download caps — remote fetches are byte-capped (5 MB preview / 100 MB analytics) and streamed, bounding memory and decompression-bomb exposure.
- SSRF for remote/hosted deployments: the local server fetches resource
URLs as given. A hosted deployment must add a host allowlist and block
private/link-local ranges. Tracked for the hosted (
v0.6) milestone.