Security hardening release
This release addresses a set of privately-reported security advisories across v0.4.109–v0.4.112. All fixes are restrictive (no functionality removed); the default stdio usage is unaffected.
SSRF
- Redirect / DNS-rebinding SSRF on fetch paths (
sparql_query, MQA): a newsafeFetch()disables blind redirect-following and re-validates every hop against the private/internal-IP guards;assertHostnameResolvesSafenow fails closed on DNS errors. Blocks redirect-to-metadata (e.g.169.254.169.254). - Second-order SSRF in
ckan_list_resources: source-portal probing is now opt-in (check_source_portal=falseby default), non-default ports are dropped, and the fan-out is capped.
Denial of service
- Decompression bomb / unbounded buffering: response size and decompression output are now capped (defaults 32 MB / 64 MB, overridable via
CKAN_MAX_RESPONSE_BYTES/CKAN_MAX_DECOMPRESSED_BYTES).
HTTP transport
- Binds
127.0.0.1by default (public bind viaCKAN_HTTP_HOST), DNS-rebinding protection withallowedHosts/allowedOrigins, anddocker-composepublishes on loopback only.
Content / integrity
- Indirect prompt-injection containment: portal free-text (dataset/resource/org/group descriptions) is wrapped in a delimited untrusted content block; portal URLs are scheme-validated and rendered in inline code.
- MQA host allowlist: exact-host validation (fixes suffix/userinfo bypass).
- Cache-key canonicalization: typed, injection-proof keys (no more collisions between different param sets).
- Error handling: upstream bodies and internal exception text are no longer reflected to callers.
- DataStore Table UI:
postMessageorigin is pinned to the host and validated.
New environment variables
CKAN_HTTP_HOST, CKAN_HTTP_ALLOWED_HOSTS, CKAN_HTTP_ALLOWED_ORIGINS, CKAN_MAX_RESPONSE_BYTES, CKAN_MAX_DECOMPRESSED_BYTES.
Credits
Reported by @Gal3m and @mrostamipoor. Thank you.
Full Changelog: v0.4.108...v0.4.112