@aborruso/ckan-mcp-server 0.4.127 → 0.4.128
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 +10 -0
- package/dist/index.js +9 -3
- package/package.json +1 -1
package/LOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# LOG
|
|
2
2
|
|
|
3
|
+
## 2026-09-28
|
|
4
|
+
|
|
5
|
+
### v0.4.128
|
|
6
|
+
|
|
7
|
+
Ships #556: every redirect hop in `makeCkanRequest` is re-validated (GHSA-279h-fmcr-4rwv), on both the Node/axios and Workers/fetch paths. Smoke 17/17.
|
|
8
|
+
|
|
9
|
+
### Security: validate every redirect hop in `makeCkanRequest` (GHSA-279h-fmcr-4rwv)
|
|
10
|
+
|
|
11
|
+
`makeCkanRequest` followed up to 5 redirects via axios without re-validating the target. The SSRF-safe agent `lookup` is skipped by Node for IP literals, so a public URL 302-ing to `http://127.0.0.1/` or `169.254.169.254` was followed, and an internal endpoint answering `success: true` was returned in full (reproduced end-to-end via httpbin `redirect-to`). Fix: axios `beforeRedirect` calls `validateServerUrl` on each hop; the Workers `fetch` branch now uses `safeFetch` (`maxHops: 5`). Side effect: `CKAN_ALLOWED_DOMAINS` now applies to redirect targets too, so a portal redirecting to another host needs both listed. The public Worker (no allowlist) is unaffected for public portals.
|
|
12
|
+
|
|
3
13
|
## 2026-09-24
|
|
4
14
|
|
|
5
15
|
### v0.4.127
|
package/dist/index.js
CHANGED
|
@@ -945,6 +945,12 @@ async function makeCkanRequest(serverUrl, action, params = {}, opts = {}) {
|
|
|
945
945
|
timeout: 3e4,
|
|
946
946
|
responseType: "arraybuffer",
|
|
947
947
|
maxRedirects: 5,
|
|
948
|
+
// Re-validate every redirect hop: Node skips the agent's `lookup` for IP
|
|
949
|
+
// literals, so a public host 302-ing to e.g. 169.254.169.254 would otherwise
|
|
950
|
+
// be followed. Also enforces CKAN_ALLOWED_DOMAINS on redirect targets.
|
|
951
|
+
beforeRedirect: (redirectOptions) => {
|
|
952
|
+
validateServerUrl(redirectOptions.href);
|
|
953
|
+
},
|
|
948
954
|
// Never route through HTTP_PROXY/HTTPS_PROXY: a proxy would connect to the
|
|
949
955
|
// target itself, bypassing the SSRF-safe lookup pinned in the agents below.
|
|
950
956
|
proxy: false,
|
|
@@ -979,7 +985,7 @@ async function makeCkanRequest(serverUrl, action, params = {}, opts = {}) {
|
|
|
979
985
|
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
980
986
|
let response;
|
|
981
987
|
try {
|
|
982
|
-
response = await
|
|
988
|
+
response = await safeFetch(fetchUrl, {
|
|
983
989
|
method: "GET",
|
|
984
990
|
signal: controller.signal,
|
|
985
991
|
headers: {
|
|
@@ -987,7 +993,7 @@ async function makeCkanRequest(serverUrl, action, params = {}, opts = {}) {
|
|
|
987
993
|
"Accept-Encoding": "identity",
|
|
988
994
|
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
989
995
|
}
|
|
990
|
-
});
|
|
996
|
+
}, { maxHops: 5 });
|
|
991
997
|
} finally {
|
|
992
998
|
clearTimeout(timeoutId);
|
|
993
999
|
}
|
|
@@ -6042,7 +6048,7 @@ var registerAllPrompts = (server) => {
|
|
|
6042
6048
|
function createServer() {
|
|
6043
6049
|
return new McpServer({
|
|
6044
6050
|
name: "ckan-mcp-server",
|
|
6045
|
-
version: "0.4.
|
|
6051
|
+
version: "0.4.128"
|
|
6046
6052
|
});
|
|
6047
6053
|
}
|
|
6048
6054
|
function registerAll(server) {
|