@aborruso/ckan-mcp-server 0.4.84 → 0.4.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # LOG
2
2
 
3
+ ## 2026-03-16
4
+
5
+ - docs(`tools/datastore.ts`): add security note to `ckan_datastore_search_sql` — clarifies SQL forwarding boundary; bump v0.4.86
6
+ - security(`tools/sparql.ts`): apply `validateServerUrl()` to `sparql_query` — blocks SSRF via private IPs (gap from GHSA-3xm7-qw7j-qc8v); 1 new test
7
+
3
8
  ## 2026-03-15
4
9
 
5
10
  - security(`utils/http.ts`): add `validateServerUrl()` — blocks SSRF via private/loopback IPs, link-local, and non-HTTP/S protocols; 15 new tests
package/dist/index.js CHANGED
@@ -2539,7 +2539,9 @@ Examples:
2539
2539
  - { server_url: "...", sql: "SELECT * FROM "abc-123" LIMIT 10" }
2540
2540
  - { server_url: "...", sql: "SELECT COUNT(*) AS total FROM "abc-123"" }
2541
2541
 
2542
- Typical workflow: ckan_package_show (get resource_id) \u2192 ckan_datastore_search_sql (run SQL on it)`,
2542
+ Typical workflow: ckan_package_show (get resource_id) \u2192 ckan_datastore_search_sql (run SQL on it)
2543
+
2544
+ Security note: SQL queries are forwarded directly to the CKAN DataStore API. The CKAN server enforces its own access controls and read-only permissions. No local database is exposed. Queries are limited to public DataStore resources on the target portal.`,
2543
2545
  inputSchema: z4.object({
2544
2546
  server_url: z4.string().url().describe("Base URL of the CKAN server (e.g., https://dati.gov.it/opendata)"),
2545
2547
  sql: z4.string().min(1).describe('SQL SELECT query; resource_id is the table name, must be double-quoted (e.g., SELECT * FROM "abc-123" LIMIT 10)'),
@@ -4217,6 +4219,7 @@ function injectLimit(query, limit) {
4217
4219
  LIMIT ${limit}`;
4218
4220
  }
4219
4221
  async function querySparqlEndpoint(endpointUrl, query) {
4222
+ validateServerUrl(endpointUrl);
4220
4223
  const url = new URL(endpointUrl);
4221
4224
  if (url.protocol !== "https:") {
4222
4225
  throw new Error("Only HTTPS endpoints are allowed");
@@ -5121,7 +5124,7 @@ var registerAllPrompts = (server2) => {
5121
5124
  function createServer() {
5122
5125
  return new McpServer({
5123
5126
  name: "ckan-mcp-server",
5124
- version: "0.4.84"
5127
+ version: "0.4.86"
5125
5128
  });
5126
5129
  }
5127
5130
  function registerAll(server2) {