mcp4openapi 0.2.3 → 0.2.5
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/README.md +22 -3
- package/dist/scripts/validate-profile.js +3 -1
- package/dist/scripts/validate-profile.js.map +1 -1
- package/dist/src/composite-executor.d.ts.map +1 -1
- package/dist/src/composite-executor.js +1 -3
- package/dist/src/composite-executor.js.map +1 -1
- package/dist/src/errors.js +0 -2
- package/dist/src/errors.js.map +1 -1
- package/dist/src/generated-schemas.d.ts +217 -30
- package/dist/src/generated-schemas.d.ts.map +1 -1
- package/dist/src/generated-schemas.js +15 -2
- package/dist/src/generated-schemas.js.map +1 -1
- package/dist/src/http-client-factory.js +3 -2
- package/dist/src/http-client-factory.js.map +1 -1
- package/dist/src/http-transport.d.ts +9 -2
- package/dist/src/http-transport.d.ts.map +1 -1
- package/dist/src/http-transport.js +165 -47
- package/dist/src/http-transport.js.map +1 -1
- package/dist/src/interceptors.d.ts +34 -0
- package/dist/src/interceptors.d.ts.map +1 -1
- package/dist/src/interceptors.js +90 -6
- package/dist/src/interceptors.js.map +1 -1
- package/dist/src/logger.js +0 -4
- package/dist/src/logger.js.map +1 -1
- package/dist/src/mcp-server.d.ts +8 -1
- package/dist/src/mcp-server.d.ts.map +1 -1
- package/dist/src/mcp-server.js +94 -22
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/metrics.js +0 -17
- package/dist/src/metrics.js.map +1 -1
- package/dist/src/oauth-provider.d.ts +29 -0
- package/dist/src/oauth-provider.d.ts.map +1 -1
- package/dist/src/oauth-provider.js +202 -20
- package/dist/src/oauth-provider.js.map +1 -1
- package/dist/src/openapi-parser.d.ts.map +1 -1
- package/dist/src/openapi-parser.js +4 -3
- package/dist/src/openapi-parser.js.map +1 -1
- package/dist/src/profile-loader.d.ts.map +1 -1
- package/dist/src/profile-loader.js +8 -0
- package/dist/src/profile-loader.js.map +1 -1
- package/dist/src/proxy-executor.d.ts +56 -0
- package/dist/src/proxy-executor.d.ts.map +1 -0
- package/dist/src/proxy-executor.js +155 -0
- package/dist/src/proxy-executor.js.map +1 -0
- package/dist/src/schema-validator.d.ts.map +1 -1
- package/dist/src/schema-validator.js +14 -1
- package/dist/src/schema-validator.js.map +1 -1
- package/dist/src/testing/mock-gitlab-server.d.ts.map +1 -1
- package/dist/src/testing/mock-gitlab-server.js +86 -29
- package/dist/src/testing/mock-gitlab-server.js.map +1 -1
- package/dist/src/testing/mock-semgrep-server.d.ts +32 -0
- package/dist/src/testing/mock-semgrep-server.d.ts.map +1 -0
- package/dist/src/testing/mock-semgrep-server.js +213 -0
- package/dist/src/testing/mock-semgrep-server.js.map +1 -0
- package/dist/src/testing/mock-youtrack-server.d.ts +11 -0
- package/dist/src/testing/mock-youtrack-server.d.ts.map +1 -0
- package/dist/src/testing/mock-youtrack-server.js +138 -0
- package/dist/src/testing/mock-youtrack-server.js.map +1 -0
- package/dist/src/testing/test-http-utils.js +1 -3
- package/dist/src/testing/test-http-utils.js.map +1 -1
- package/dist/src/testing/test-types.d.ts +26 -1
- package/dist/src/testing/test-types.d.ts.map +1 -1
- package/dist/src/tool-generator.d.ts +23 -0
- package/dist/src/tool-generator.d.ts.map +1 -1
- package/dist/src/tool-generator.js +55 -5
- package/dist/src/tool-generator.js.map +1 -1
- package/dist/src/types/profile.d.ts +41 -3
- package/dist/src/types/profile.d.ts.map +1 -1
- package/dist/src/validation-utils.d.ts.map +1 -1
- package/dist/src/validation-utils.js +24 -2
- package/dist/src/validation-utils.js.map +1 -1
- package/package.json +3 -3
- package/profile-schema.json +70 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generated-schemas.js","sourceRoot":"","sources":["../../src/generated-schemas.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"generated-schemas.js","sourceRoot":"","sources":["../../src/generated-schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,9 @@ import { ConfigurationError, AuthenticationError } from './errors.js';
|
|
|
11
11
|
* Handles both global and session-specific clients
|
|
12
12
|
*/
|
|
13
13
|
export class HttpClientFactory {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
constructor() {
|
|
15
|
+
this.sessionClients = new Map();
|
|
16
|
+
}
|
|
16
17
|
/**
|
|
17
18
|
* Create global HTTP client (for stdio transport)
|
|
18
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client-factory.js","sourceRoot":"","sources":["../../src/http-client-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQtE;;;GAGG;AACH,MAAM,OAAO,iBAAiB;
|
|
1
|
+
{"version":3,"file":"http-client-factory.js","sourceRoot":"","sources":["../../src/http-client-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,9 +50,10 @@ export declare class HttpTransport {
|
|
|
50
50
|
*/
|
|
51
51
|
private matchOrigin;
|
|
52
52
|
/**
|
|
53
|
-
* Check if IP address is within CIDR range
|
|
53
|
+
* Check if IP address is within CIDR range (IPv4 or IPv6)
|
|
54
54
|
*
|
|
55
55
|
* Example: '192.168.1.50' matches '192.168.1.0/24'
|
|
56
|
+
* '2001:db8::1' matches '2001:db8::/32'
|
|
56
57
|
*/
|
|
57
58
|
private matchCIDR;
|
|
58
59
|
/**
|
|
@@ -60,7 +61,13 @@ export declare class HttpTransport {
|
|
|
60
61
|
*
|
|
61
62
|
* Example: '192.168.1.1' -> 3232235777
|
|
62
63
|
*/
|
|
63
|
-
private
|
|
64
|
+
private ipv4ToInt;
|
|
65
|
+
/**
|
|
66
|
+
* Convert IPv6 address to 128-bit BigInt
|
|
67
|
+
*/
|
|
68
|
+
private ipv6ToBigInt;
|
|
69
|
+
private ipv6Mask;
|
|
70
|
+
private stripIpv6Brackets;
|
|
64
71
|
/**
|
|
65
72
|
* Create configured rate limiter or a passthrough handler when disabled
|
|
66
73
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/http-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/http-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAIV,mBAAmB,EAEpB,MAAM,2BAA2B,CAAC;AAYnC,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,cAAc,CAA6E;IACnG,OAAO,CAAC,aAAa,CAAsC;IAG3D,OAAO,CAAC,wBAAwB,CAA6G;gBAEjI,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM;IAgCvD;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA6HvB,OAAO,CAAC,qBAAqB,CAAS;IAEtC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IA0CvB;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;IAuBnB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAgDjB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAmBjB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6EpB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,iBAAiB;IAIzB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,sBAAsB;IAI9B;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAqcnB;;;;OAIG;YACW,aAAa;IAoB3B;;;;;OAKG;IACH;;;OAGG;IACH,OAAO,CAAC,QAAQ;YAkBF,iBAAiB;IAqE/B;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IA4CxB;;;;OAIG;YACW,UAAU;IAqNxB;;;;OAIG;YACW,SAAS;IAkDvB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAmCpB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6CtB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAatB;;;;OAIG;IACI,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IA6B9D;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAoCtB;;OAEG;IACH,OAAO,CAAC,yBAAyB,CAA0C;IAE3E;;;;OAIG;IACI,kBAAkB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAItE;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACI,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK7D;;;;;OAKG;IACU,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BzE;;;;;OAKG;YACW,kBAAkB;IA+EhC;;OAEG;IACI,iBAAiB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAInG;;OAEG;IACI,gBAAgB,IAAI,OAAO;IAIlC;;OAEG;IACI,YAAY,IAAI,MAAM;IAmB7B;;OAEG;IACI,wBAAwB,IAAI,MAAM;IAIzC;;OAEG;IACI,cAAc,IAAI,MAAM,EAAE;IAIjC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqEnC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBnC"}
|
|
@@ -11,6 +11,7 @@ import express from 'express';
|
|
|
11
11
|
import https from 'https';
|
|
12
12
|
import fs from 'fs';
|
|
13
13
|
import crypto from 'crypto';
|
|
14
|
+
import { isIP } from 'node:net';
|
|
14
15
|
import rateLimit from 'express-rate-limit';
|
|
15
16
|
import { isInitializeRequest } from './jsonrpc-validator.js';
|
|
16
17
|
import { MetricsCollector } from './metrics.js';
|
|
@@ -20,20 +21,23 @@ import { escapeHtmlSafe } from './validation-utils.js';
|
|
|
20
21
|
// Default maximum token length (1000 characters)
|
|
21
22
|
const DEFAULT_MAX_TOKEN_LENGTH = 1000;
|
|
22
23
|
export class HttpTransport {
|
|
23
|
-
app;
|
|
24
|
-
server = null;
|
|
25
|
-
sessions = new Map();
|
|
26
|
-
config;
|
|
27
|
-
logger;
|
|
28
|
-
metrics = null;
|
|
29
|
-
cleanupInterval = null;
|
|
30
|
-
messageHandler = null;
|
|
31
|
-
oauthProvider = null;
|
|
32
|
-
// Map access_token -> { refreshToken, expiresAt, clientId, scopes }
|
|
33
|
-
// Used to bridge /oauth/token endpoint (where we see OAuthTokens) and session initialization (where we only see access token)
|
|
34
|
-
oauthTokensByAccessToken = new Map();
|
|
35
24
|
constructor(config, logger) {
|
|
36
|
-
this.
|
|
25
|
+
this.server = null;
|
|
26
|
+
this.sessions = new Map();
|
|
27
|
+
this.metrics = null;
|
|
28
|
+
this.cleanupInterval = null;
|
|
29
|
+
this.messageHandler = null;
|
|
30
|
+
this.oauthProvider = null;
|
|
31
|
+
// Map access_token -> { refreshToken, expiresAt, clientId, scopes }
|
|
32
|
+
// Used to bridge /oauth/token endpoint (where we see OAuthTokens) and session initialization (where we only see access token)
|
|
33
|
+
this.oauthTokensByAccessToken = new Map();
|
|
34
|
+
this.hasWarnedAboutBinding = false;
|
|
35
|
+
/**
|
|
36
|
+
* Session destruction listeners for cleanup in other components
|
|
37
|
+
*/
|
|
38
|
+
this.sessionDestroyedListeners = [];
|
|
39
|
+
// Freeze config to prevent runtime mutation of security-critical settings (allowedOrigins, rate limits, etc.)
|
|
40
|
+
this.config = Object.freeze({ ...config });
|
|
37
41
|
this.logger = logger;
|
|
38
42
|
// Initialize metrics if enabled
|
|
39
43
|
if (config.metricsEnabled) {
|
|
@@ -77,6 +81,26 @@ export class HttpTransport {
|
|
|
77
81
|
});
|
|
78
82
|
next();
|
|
79
83
|
});
|
|
84
|
+
// DNS rebinding protection when binding to localhost
|
|
85
|
+
// Deny requests with mismatched Host headers to prevent DNS rebinding attacks
|
|
86
|
+
// Applies when server host is localhost/127.0.0.1, regardless of auth configuration
|
|
87
|
+
this.app.use((req, res, next) => {
|
|
88
|
+
const hostCfg = this.config.host?.toLowerCase();
|
|
89
|
+
if (hostCfg === 'localhost' || hostCfg === '127.0.0.1') {
|
|
90
|
+
const hostHeader = (req.headers['host'] || '').toString().toLowerCase();
|
|
91
|
+
const expectedHosts = new Set(['localhost', '127.0.0.1']);
|
|
92
|
+
const headerHostOnly = hostHeader.split(':')[0];
|
|
93
|
+
if (!expectedHosts.has(headerHostOnly)) {
|
|
94
|
+
this.logger.warn('DNS rebinding protection: invalid Host header', {
|
|
95
|
+
hostHeader,
|
|
96
|
+
expected: Array.from(expectedHosts),
|
|
97
|
+
});
|
|
98
|
+
res.status(403).json({ error: 'Forbidden' });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
next();
|
|
103
|
+
});
|
|
80
104
|
// JSON body parser
|
|
81
105
|
this.app.use(express.json());
|
|
82
106
|
// Metrics: Track request start time
|
|
@@ -155,7 +179,6 @@ export class HttpTransport {
|
|
|
155
179
|
next();
|
|
156
180
|
});
|
|
157
181
|
}
|
|
158
|
-
hasWarnedAboutBinding = false;
|
|
159
182
|
/**
|
|
160
183
|
* Check if origin is allowed
|
|
161
184
|
*
|
|
@@ -214,43 +237,64 @@ export class HttpTransport {
|
|
|
214
237
|
* - CIDR: '192.168.1.0/24' matches '192.168.1.1' through '192.168.1.254'
|
|
215
238
|
*/
|
|
216
239
|
matchOrigin(hostname, pattern) {
|
|
240
|
+
const normalizedHost = this.stripIpv6Brackets(hostname);
|
|
241
|
+
const normalizedPattern = this.stripIpv6Brackets(pattern);
|
|
217
242
|
// Exact match
|
|
218
|
-
if (
|
|
243
|
+
if (normalizedHost === normalizedPattern) {
|
|
219
244
|
return true;
|
|
220
245
|
}
|
|
221
246
|
// Wildcard subdomain match (*.example.com)
|
|
222
|
-
if (
|
|
223
|
-
const domain =
|
|
224
|
-
return
|
|
247
|
+
if (normalizedPattern.startsWith('*.')) {
|
|
248
|
+
const domain = normalizedPattern.substring(2); // Remove '*.'
|
|
249
|
+
return normalizedHost.endsWith('.' + domain) || normalizedHost === domain;
|
|
225
250
|
}
|
|
226
|
-
// CIDR match (IPv4
|
|
227
|
-
if (
|
|
228
|
-
return this.matchCIDR(
|
|
251
|
+
// CIDR match (IPv4/IPv6)
|
|
252
|
+
if (normalizedPattern.includes('/')) {
|
|
253
|
+
return this.matchCIDR(normalizedHost, normalizedPattern);
|
|
229
254
|
}
|
|
230
255
|
return false;
|
|
231
256
|
}
|
|
232
257
|
/**
|
|
233
|
-
* Check if IP address is within CIDR range
|
|
258
|
+
* Check if IP address is within CIDR range (IPv4 or IPv6)
|
|
234
259
|
*
|
|
235
260
|
* Example: '192.168.1.50' matches '192.168.1.0/24'
|
|
261
|
+
* '2001:db8::1' matches '2001:db8::/32'
|
|
236
262
|
*/
|
|
237
263
|
matchCIDR(ip, cidr) {
|
|
238
|
-
|
|
239
|
-
const
|
|
264
|
+
const [rawRange, bits] = cidr.split('/');
|
|
265
|
+
const range = this.stripIpv6Brackets(rawRange);
|
|
240
266
|
const maskBits = parseInt(bits, 10);
|
|
241
|
-
if (isNaN(maskBits)
|
|
242
|
-
|
|
267
|
+
if (isNaN(maskBits)) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
const ipVersion = isIP(ip);
|
|
271
|
+
const rangeVersion = isIP(range);
|
|
272
|
+
if (ipVersion === 0 || rangeVersion === 0 || ipVersion !== rangeVersion) {
|
|
243
273
|
return false;
|
|
244
274
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
275
|
+
if (ipVersion === 4) {
|
|
276
|
+
if (maskBits < 0 || maskBits > 32) {
|
|
277
|
+
this.logger.warn('Invalid CIDR mask bits', { cidr });
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
const ipInt = this.ipv4ToInt(ip);
|
|
281
|
+
const rangeInt = this.ipv4ToInt(range);
|
|
282
|
+
if (ipInt === null || rangeInt === null) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
const mask = (0xFFFFFFFF << (32 - maskBits)) >>> 0;
|
|
286
|
+
return (ipInt & mask) === (rangeInt & mask);
|
|
287
|
+
}
|
|
288
|
+
if (maskBits < 0 || maskBits > 128) {
|
|
289
|
+
this.logger.warn('Invalid IPv6 CIDR mask bits', { cidr });
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
const ipInt = this.ipv6ToBigInt(ip);
|
|
293
|
+
const rangeInt = this.ipv6ToBigInt(range);
|
|
248
294
|
if (ipInt === null || rangeInt === null) {
|
|
249
295
|
return false;
|
|
250
296
|
}
|
|
251
|
-
|
|
252
|
-
const mask = (0xFFFFFFFF << (32 - maskBits)) >>> 0;
|
|
253
|
-
// Compare network portions
|
|
297
|
+
const mask = this.ipv6Mask(maskBits);
|
|
254
298
|
return (ipInt & mask) === (rangeInt & mask);
|
|
255
299
|
}
|
|
256
300
|
/**
|
|
@@ -258,7 +302,7 @@ export class HttpTransport {
|
|
|
258
302
|
*
|
|
259
303
|
* Example: '192.168.1.1' -> 3232235777
|
|
260
304
|
*/
|
|
261
|
-
|
|
305
|
+
ipv4ToInt(ip) {
|
|
262
306
|
const parts = ip.split('.');
|
|
263
307
|
if (parts.length !== 4) {
|
|
264
308
|
return null;
|
|
@@ -273,6 +317,83 @@ export class HttpTransport {
|
|
|
273
317
|
}
|
|
274
318
|
return result >>> 0; // Unsigned
|
|
275
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Convert IPv6 address to 128-bit BigInt
|
|
322
|
+
*/
|
|
323
|
+
ipv6ToBigInt(ip) {
|
|
324
|
+
const cleaned = this.stripIpv6Brackets(ip);
|
|
325
|
+
// Handle IPv4-mapped IPv6 (e.g., ::ffff:192.168.0.1)
|
|
326
|
+
let ipv4Tail = null;
|
|
327
|
+
let base = cleaned;
|
|
328
|
+
if (cleaned.includes('.')) {
|
|
329
|
+
const lastColon = cleaned.lastIndexOf(':');
|
|
330
|
+
if (lastColon === -1)
|
|
331
|
+
return null;
|
|
332
|
+
const ipv4Part = cleaned.slice(lastColon + 1);
|
|
333
|
+
ipv4Tail = this.ipv4ToInt(ipv4Part);
|
|
334
|
+
if (ipv4Tail === null)
|
|
335
|
+
return null;
|
|
336
|
+
base = cleaned.slice(0, lastColon);
|
|
337
|
+
}
|
|
338
|
+
const parts = base.split('::');
|
|
339
|
+
if (parts.length > 2) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
const head = parts[0] ? parts[0].split(':') : [];
|
|
343
|
+
const tail = parts.length === 2 && parts[1] ? parts[1].split(':') : [];
|
|
344
|
+
if (head.some(p => p === '') || tail.some(p => p === '')) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const totalSegmentsNeeded = 8 - (ipv4Tail !== null ? 2 : 0);
|
|
348
|
+
let segments = [];
|
|
349
|
+
const parseHextets = (items) => {
|
|
350
|
+
const result = [];
|
|
351
|
+
for (const part of items) {
|
|
352
|
+
const num = parseInt(part || '0', 16);
|
|
353
|
+
if (isNaN(num) || num < 0 || num > 0xFFFF) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
result.push(num);
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
359
|
+
};
|
|
360
|
+
const headVals = parseHextets(head);
|
|
361
|
+
const tailVals = parseHextets(tail);
|
|
362
|
+
if (!headVals || !tailVals) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const missing = totalSegmentsNeeded - (headVals.length + tailVals.length);
|
|
366
|
+
if (missing < 0) {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
segments = [...headVals, ...Array(missing).fill(0), ...tailVals];
|
|
370
|
+
if (segments.length !== totalSegmentsNeeded) {
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
if (ipv4Tail !== null) {
|
|
374
|
+
const high = (ipv4Tail >>> 16) & 0xFFFF;
|
|
375
|
+
const low = ipv4Tail & 0xFFFF;
|
|
376
|
+
segments.push(high, low);
|
|
377
|
+
}
|
|
378
|
+
if (segments.length !== 8) {
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
let value = 0n;
|
|
382
|
+
for (const part of segments) {
|
|
383
|
+
value = (value << 16n) + BigInt(part);
|
|
384
|
+
}
|
|
385
|
+
return value;
|
|
386
|
+
}
|
|
387
|
+
ipv6Mask(maskBits) {
|
|
388
|
+
if (maskBits === 0) {
|
|
389
|
+
return 0n;
|
|
390
|
+
}
|
|
391
|
+
const ones = (1n << BigInt(maskBits)) - 1n;
|
|
392
|
+
return BigInt.asUintN(128, ones << BigInt(128 - maskBits));
|
|
393
|
+
}
|
|
394
|
+
stripIpv6Brackets(value) {
|
|
395
|
+
return value.replace(/^\[/, '').replace(/\]$/, '');
|
|
396
|
+
}
|
|
276
397
|
/**
|
|
277
398
|
* Create configured rate limiter or a passthrough handler when disabled
|
|
278
399
|
*
|
|
@@ -641,21 +762,22 @@ export class HttpTransport {
|
|
|
641
762
|
});
|
|
642
763
|
// Main MCP endpoint - POST for sending messages
|
|
643
764
|
this.app.post('/mcp', mcpRateLimiter, this.handlePost.bind(this));
|
|
644
|
-
//
|
|
765
|
+
// CORS preflight handler
|
|
645
766
|
this.app.options('/mcp', (req, res) => {
|
|
646
767
|
const origin = req.headers.origin;
|
|
647
|
-
//
|
|
768
|
+
// Only send CORS headers for explicitly allowed origins; otherwise reject
|
|
648
769
|
if (origin && this.isAllowedOrigin(origin)) {
|
|
770
|
+
// nosemgrep: javascript.express.security.cors-misconfiguration.cors-misconfiguration
|
|
649
771
|
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
772
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
|
|
773
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept, Mcp-Session-Id');
|
|
774
|
+
// We do not allow credentials; prevents cookie-based attacks by default
|
|
775
|
+
res.setHeader('Access-Control-Allow-Credentials', 'false');
|
|
776
|
+
res.setHeader('Access-Control-Max-Age', '86400'); // 24 hours cache
|
|
777
|
+
return res.status(HTTP_STATUS.OK).send();
|
|
650
778
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
res.setHeader('Access-Control-Allow-Origin', 'null');
|
|
654
|
-
}
|
|
655
|
-
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
|
|
656
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept, Mcp-Session-Id');
|
|
657
|
-
res.setHeader('Access-Control-Max-Age', '86400'); // 24 hours
|
|
658
|
-
res.status(HTTP_STATUS.OK).send();
|
|
779
|
+
// Disallowed origin: do not echo origin or emit permissive headers
|
|
780
|
+
res.status(HTTP_STATUS.FORBIDDEN).json({ error: 'Forbidden', message: 'Origin not allowed' });
|
|
659
781
|
});
|
|
660
782
|
this.logger.info('Registered POST /mcp route');
|
|
661
783
|
// Main MCP endpoint - GET for SSE streaming
|
|
@@ -1373,10 +1495,6 @@ export class HttpTransport {
|
|
|
1373
1495
|
}
|
|
1374
1496
|
}
|
|
1375
1497
|
}
|
|
1376
|
-
/**
|
|
1377
|
-
* Session destruction listeners for cleanup in other components
|
|
1378
|
-
*/
|
|
1379
|
-
sessionDestroyedListeners = [];
|
|
1380
1498
|
/**
|
|
1381
1499
|
* Register listener for session destruction events
|
|
1382
1500
|
*
|