@theia/core 1.74.0-next.47 → 1.74.0-next.51
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/lib/electron-node/hosting/electron-backend-hosting-module.d.ts.map +1 -1
- package/lib/electron-node/hosting/electron-backend-hosting-module.js +7 -0
- package/lib/electron-node/hosting/electron-backend-hosting-module.js.map +1 -1
- package/lib/electron-node/hosting/electron-backend-hosting-module.spec.d.ts +2 -0
- package/lib/electron-node/hosting/electron-backend-hosting-module.spec.d.ts.map +1 -0
- package/lib/electron-node/hosting/electron-backend-hosting-module.spec.js +39 -0
- package/lib/electron-node/hosting/electron-backend-hosting-module.spec.js.map +1 -0
- package/lib/node/hosting/backend-hosting-module.d.ts.map +1 -1
- package/lib/node/hosting/backend-hosting-module.js +4 -1
- package/lib/node/hosting/backend-hosting-module.js.map +1 -1
- package/lib/node/hosting/browser-connection-token.d.ts +29 -1
- package/lib/node/hosting/browser-connection-token.d.ts.map +1 -1
- package/lib/node/hosting/browser-connection-token.js +25 -1
- package/lib/node/hosting/browser-connection-token.js.map +1 -1
- package/lib/node/hosting/browser-connection-token.spec.js +70 -0
- package/lib/node/hosting/browser-connection-token.spec.js.map +1 -1
- package/lib/node/index.d.ts +1 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +3 -1
- package/lib/node/index.js.map +1 -1
- package/package.json +4 -4
- package/src/electron-node/hosting/electron-backend-hosting-module.spec.ts +42 -0
- package/src/electron-node/hosting/electron-backend-hosting-module.ts +8 -0
- package/src/node/hosting/backend-hosting-module.ts +5 -2
- package/src/node/hosting/browser-connection-token.spec.ts +92 -0
- package/src/node/hosting/browser-connection-token.ts +45 -1
- package/src/node/index.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-backend-hosting-module.d.ts","sourceRoot":"","sources":["../../../src/electron-node/hosting/electron-backend-hosting-module.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;;
|
|
1
|
+
{"version":3,"file":"electron-backend-hosting-module.d.ts","sourceRoot":"","sources":["../../../src/electron-node/hosting/electron-backend-hosting-module.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;;AAK5C,wBAUG"}
|
|
@@ -17,9 +17,16 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
const inversify_1 = require("inversify");
|
|
19
19
|
const ws_request_validators_1 = require("../../node/ws-request-validators");
|
|
20
|
+
const browser_connection_token_1 = require("../../node/hosting/browser-connection-token");
|
|
20
21
|
const electron_ws_origin_validator_1 = require("./electron-ws-origin-validator");
|
|
21
22
|
exports.default = new inversify_1.ContainerModule(bind => {
|
|
22
23
|
bind(electron_ws_origin_validator_1.ElectronWsOriginValidator).toSelf().inSingletonScope();
|
|
23
24
|
bind(ws_request_validators_1.WsRequestValidatorContribution).toService(electron_ws_origin_validator_1.ElectronWsOriginValidator);
|
|
25
|
+
// Electron uses its own `ElectronSecurityToken`, so the connection-token cookie is not used.
|
|
26
|
+
// Bind a no-op validator so consumers can inject it uniformly.
|
|
27
|
+
const noopValidator = {
|
|
28
|
+
validateRequest: (_req, _res, next) => next()
|
|
29
|
+
};
|
|
30
|
+
bind(browser_connection_token_1.HttpConnectionValidator).toConstantValue(noopValidator);
|
|
24
31
|
});
|
|
25
32
|
//# sourceMappingURL=electron-backend-hosting-module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-backend-hosting-module.js","sourceRoot":"","sources":["../../../src/electron-node/hosting/electron-backend-hosting-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,yCAA4C;AAC5C,4EAAkF;AAClF,iFAA2E;AAE3E,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,wDAAyB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC5D,IAAI,CAAC,sDAA8B,CAAC,CAAC,SAAS,CAAC,wDAAyB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"electron-backend-hosting-module.js","sourceRoot":"","sources":["../../../src/electron-node/hosting/electron-backend-hosting-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,yCAA4C;AAC5C,4EAAkF;AAClF,0FAAsF;AACtF,iFAA2E;AAE3E,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,wDAAyB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC5D,IAAI,CAAC,sDAA8B,CAAC,CAAC,SAAS,CAAC,wDAAyB,CAAC,CAAC;IAE1E,6FAA6F;IAC7F,+DAA+D;IAC/D,MAAM,aAAa,GAA4B;QAC3C,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;KAChD,CAAC;IACF,IAAI,CAAC,kDAAuB,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electron-backend-hosting-module.spec.d.ts","sourceRoot":"","sources":["../../../src/electron-node/hosting/electron-backend-hosting-module.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 EclipseSource GmbH and others.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const chai_1 = require("chai");
|
|
19
|
+
const inversify_1 = require("inversify");
|
|
20
|
+
const electron_backend_hosting_module_1 = require("./electron-backend-hosting-module");
|
|
21
|
+
const browser_connection_token_1 = require("../../node/hosting/browser-connection-token");
|
|
22
|
+
describe('electron-backend-hosting-module', () => {
|
|
23
|
+
it('should bind a no-op HttpConnectionValidator that calls next() unconditionally', () => {
|
|
24
|
+
const container = new inversify_1.Container();
|
|
25
|
+
container.load(electron_backend_hosting_module_1.default);
|
|
26
|
+
const validator = container.get(browser_connection_token_1.HttpConnectionValidator);
|
|
27
|
+
let nextCalled = false;
|
|
28
|
+
let sentStatus;
|
|
29
|
+
// No cookie provided: the no-op validator must still call next() and never send a status.
|
|
30
|
+
const req = { headers: {} };
|
|
31
|
+
const res = { sendStatus: (status) => { sentStatus = status; } };
|
|
32
|
+
const next = () => { nextCalled = true; };
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
validator.validateRequest(req, res, next);
|
|
35
|
+
(0, chai_1.expect)(nextCalled).to.be.true;
|
|
36
|
+
(0, chai_1.expect)(sentStatus).to.be.undefined;
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=electron-backend-hosting-module.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electron-backend-hosting-module.spec.js","sourceRoot":"","sources":["../../../src/electron-node/hosting/electron-backend-hosting-module.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,+BAA8B;AAC9B,yCAAsC;AACtC,uFAA6E;AAC7E,0FAAsF;AAEtF,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAE7C,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACrF,MAAM,SAAS,GAAG,IAAI,qBAAS,EAAE,CAAC;QAClC,SAAS,CAAC,IAAI,CAAC,yCAA4B,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAA0B,kDAAuB,CAAC,CAAC;QAElF,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,UAA8B,CAAC;QACnC,0FAA0F;QAC1F,MAAM,GAAG,GAAG,EAAE,OAAO,EAAE,EAAwC,EAAE,CAAC;QAClE,MAAM,GAAG,GAAG,EAAE,UAAU,EAAE,CAAC,MAAc,EAAE,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,GAAG,GAAS,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEhD,8DAA8D;QAC9D,SAAS,CAAC,eAAe,CAAC,GAAU,EAAE,GAAU,EAAE,IAAW,CAAC,CAAC;QAE/D,IAAA,aAAM,EAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC9B,IAAA,aAAM,EAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC;IACvC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-hosting-module.d.ts","sourceRoot":"","sources":["../../../src/node/hosting/backend-hosting-module.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;;AAS5C,
|
|
1
|
+
{"version":3,"file":"backend-hosting-module.d.ts","sourceRoot":"","sources":["../../../src/node/hosting/backend-hosting-module.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;;AAS5C,wBAaG"}
|
|
@@ -25,10 +25,13 @@ exports.default = new inversify_1.ContainerModule(bind => {
|
|
|
25
25
|
bind(backend_application_hosts_1.BackendApplicationHosts).toSelf().inSingletonScope();
|
|
26
26
|
bind(ws_origin_validator_1.WsOriginValidator).toSelf().inSingletonScope();
|
|
27
27
|
bind(ws_request_validators_1.WsRequestValidatorContribution).toService(ws_origin_validator_1.WsOriginValidator);
|
|
28
|
-
// Cookie-based connection token
|
|
28
|
+
// Cookie-based connection token. It is validated on WebSocket upgrades and bootstrapped
|
|
29
|
+
// (set as a cookie) on every HTTP request; HTTP enforcement is opt-in per route via
|
|
30
|
+
// `HttpConnectionValidator`.
|
|
29
31
|
bind(browser_connection_token_1.BrowserConnectionToken).toConstantValue((0, browser_connection_token_1.createBrowserConnectionToken)());
|
|
30
32
|
bind(browser_connection_token_1.BrowserConnectionTokenBackendContribution).toSelf().inSingletonScope();
|
|
31
33
|
bind(backend_application_1.BackendApplicationContribution).toService(browser_connection_token_1.BrowserConnectionTokenBackendContribution);
|
|
32
34
|
bind(ws_request_validators_1.WsRequestValidatorContribution).toService(browser_connection_token_1.BrowserConnectionTokenBackendContribution);
|
|
35
|
+
bind(browser_connection_token_1.HttpConnectionValidator).toService(browser_connection_token_1.BrowserConnectionTokenBackendContribution);
|
|
33
36
|
});
|
|
34
37
|
//# sourceMappingURL=backend-hosting-module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-hosting-module.js","sourceRoot":"","sources":["../../../src/node/hosting/backend-hosting-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,yCAA4C;AAC5C,gEAAwE;AACxE,oEAA0E;AAC1E,2EAAsE;AACtE,yEAEoC;AACpC,+DAA0D;AAE1D,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,mDAAuB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC1D,IAAI,CAAC,uCAAiB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACpD,IAAI,CAAC,sDAA8B,CAAC,CAAC,SAAS,CAAC,uCAAiB,CAAC,CAAC;IAElE,
|
|
1
|
+
{"version":3,"file":"backend-hosting-module.js","sourceRoot":"","sources":["../../../src/node/hosting/backend-hosting-module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,yCAA4C;AAC5C,gEAAwE;AACxE,oEAA0E;AAC1E,2EAAsE;AACtE,yEAEoC;AACpC,+DAA0D;AAE1D,kBAAe,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;IACtC,IAAI,CAAC,mDAAuB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC1D,IAAI,CAAC,uCAAiB,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACpD,IAAI,CAAC,sDAA8B,CAAC,CAAC,SAAS,CAAC,uCAAiB,CAAC,CAAC;IAElE,wFAAwF;IACxF,oFAAoF;IACpF,6BAA6B;IAC7B,IAAI,CAAC,iDAAsB,CAAC,CAAC,eAAe,CAAC,IAAA,uDAA4B,GAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,oEAAyC,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC5E,IAAI,CAAC,oDAA8B,CAAC,CAAC,SAAS,CAAC,oEAAyC,CAAC,CAAC;IAC1F,IAAI,CAAC,sDAA8B,CAAC,CAAC,SAAS,CAAC,oEAAyC,CAAC,CAAC;IAC1F,IAAI,CAAC,kDAAuB,CAAC,CAAC,SAAS,CAAC,oEAAyC,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC"}
|
|
@@ -8,6 +8,24 @@ export declare const BROWSER_TOKEN_COOKIE_NAME = "theia-connection-token";
|
|
|
8
8
|
export interface BrowserConnectionToken {
|
|
9
9
|
value: string;
|
|
10
10
|
}
|
|
11
|
+
export declare const HttpConnectionValidator: unique symbol;
|
|
12
|
+
/**
|
|
13
|
+
* Express middleware provider that rejects HTTP requests lacking a valid connection token.
|
|
14
|
+
*
|
|
15
|
+
* The connection-token cookie is only *bootstrapped* globally (see
|
|
16
|
+
* {@link BrowserConnectionTokenBackendContribution}); enforcement is opt-in per route.
|
|
17
|
+
* Security-sensitive HTTP endpoints (e.g. the filesystem upload/download routes) should
|
|
18
|
+
* inject this and apply {@link validateRequest} as route middleware. Non-sensitive routes
|
|
19
|
+
* (the initial HTML page, static assets) must not use it, as they legitimately have no
|
|
20
|
+
* cookie yet on the very first page load.
|
|
21
|
+
*/
|
|
22
|
+
export interface HttpConnectionValidator {
|
|
23
|
+
/**
|
|
24
|
+
* Express middleware that calls `next()` when the request carries a valid connection-token
|
|
25
|
+
* cookie (or when running in Electron) and responds with `403` otherwise.
|
|
26
|
+
*/
|
|
27
|
+
validateRequest(req: express.Request, res: express.Response, next: express.NextFunction): void;
|
|
28
|
+
}
|
|
11
29
|
/**
|
|
12
30
|
* Validates WebSocket and HTTP requests using a cookie-based connection token.
|
|
13
31
|
*
|
|
@@ -15,12 +33,17 @@ export interface BrowserConnectionToken {
|
|
|
15
33
|
* as a `SameSite=Strict; HttpOnly` cookie on the first page load. Cross-origin pages
|
|
16
34
|
* cannot obtain or send this cookie, so their requests are rejected.
|
|
17
35
|
*
|
|
36
|
+
* The cookie is *bootstrapped* for every HTTP request (via {@link expressMiddleware}) so that
|
|
37
|
+
* browsers always receive it, but HTTP requests are only *rejected* on routes that opt in to
|
|
38
|
+
* enforcement via {@link validateRequest} (see {@link HttpConnectionValidator}). WebSocket
|
|
39
|
+
* upgrades are always validated (see {@link allowWsUpgrade}).
|
|
40
|
+
*
|
|
18
41
|
* This complements the origin validator: non-browser callers that omit the Origin
|
|
19
42
|
* header (e.g. Node.js scripts) still cannot reach the backend without the cookie.
|
|
20
43
|
*
|
|
21
44
|
* Skipped in Electron deployments (which use their own `ElectronSecurityToken`).
|
|
22
45
|
*/
|
|
23
|
-
export declare class BrowserConnectionTokenBackendContribution implements BackendApplicationContribution, WsRequestValidatorContribution {
|
|
46
|
+
export declare class BrowserConnectionTokenBackendContribution implements BackendApplicationContribution, WsRequestValidatorContribution, HttpConnectionValidator {
|
|
24
47
|
protected readonly browserConnectionToken: BrowserConnectionToken;
|
|
25
48
|
protected readonly earlyMiddleware: EarlyExpressMiddleware;
|
|
26
49
|
/**
|
|
@@ -35,6 +58,11 @@ export declare class BrowserConnectionTokenBackendContribution implements Backen
|
|
|
35
58
|
* cannot provide the `SameSite=Strict` cookie either, so they are rejected.
|
|
36
59
|
*/
|
|
37
60
|
allowWsUpgrade(request: http.IncomingMessage): MaybePromise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Reject the request with `403` unless it carries a valid connection-token cookie.
|
|
63
|
+
* Always allows the request in Electron deployments, consistent with {@link allowWsUpgrade}.
|
|
64
|
+
*/
|
|
65
|
+
validateRequest(req: express.Request, res: express.Response, next: express.NextFunction): void;
|
|
38
66
|
protected expressMiddleware(req: express.Request, res: express.Response, next: express.NextFunction): void;
|
|
39
67
|
protected getTokenFromCookie(req: http.IncomingMessage): string | undefined;
|
|
40
68
|
protected isTokenValid(token: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-connection-token.d.ts","sourceRoot":"","sources":["../../../src/node/hosting/browser-connection-token.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,OAAO,GAAG,QAAQ,SAAS,CAAC,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAG1E,eAAO,MAAM,sBAAsB,eAAmC,CAAC;AAEvE,eAAO,MAAM,yBAAyB,2BAA2B,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,MAAM,CAAC;CACjB;AAED
|
|
1
|
+
{"version":3,"file":"browser-connection-token.d.ts","sourceRoot":"","sources":["../../../src/node/hosting/browser-connection-token.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,OAAO,GAAG,QAAQ,SAAS,CAAC,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAG1E,eAAO,MAAM,sBAAsB,eAAmC,CAAC;AAEvE,eAAO,MAAM,yBAAyB,2BAA2B,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACpC;;;OAGG;IACH,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;CAClG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,yCAA0C,YAAW,8BAA8B,EAAE,8BAA8B,EAAE,uBAAuB;IAGrJ,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IAGlE,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,sBAAsB,CAAC;IAE3D;;;;OAIG;IACH,UAAU,IAAI,IAAI;IAOlB;;;;OAIG;IACH,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,GAAG,YAAY,CAAC,OAAO,CAAC;IAapE;;;OAGG;IACH,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,IAAI;IAe9F,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,IAAI;IAc1G,SAAS,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,GAAG,MAAM,GAAG,SAAS;IAQ3E,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAUjD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,sBAAsB,CAErE"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.BrowserConnectionTokenBackendContribution = exports.BROWSER_TOKEN_COOKIE_NAME = exports.BrowserConnectionToken = void 0;
|
|
18
|
+
exports.BrowserConnectionTokenBackendContribution = exports.HttpConnectionValidator = exports.BROWSER_TOKEN_COOKIE_NAME = exports.BrowserConnectionToken = void 0;
|
|
19
19
|
exports.createBrowserConnectionToken = createBrowserConnectionToken;
|
|
20
20
|
const tslib_1 = require("tslib");
|
|
21
21
|
const cookie = require("cookie");
|
|
@@ -26,6 +26,7 @@ const backend_application_1 = require("../backend-application");
|
|
|
26
26
|
const uuid_1 = require("../../common/uuid");
|
|
27
27
|
exports.BrowserConnectionToken = Symbol('BrowserConnectionToken');
|
|
28
28
|
exports.BROWSER_TOKEN_COOKIE_NAME = 'theia-connection-token';
|
|
29
|
+
exports.HttpConnectionValidator = Symbol('HttpConnectionValidator');
|
|
29
30
|
/**
|
|
30
31
|
* Validates WebSocket and HTTP requests using a cookie-based connection token.
|
|
31
32
|
*
|
|
@@ -33,6 +34,11 @@ exports.BROWSER_TOKEN_COOKIE_NAME = 'theia-connection-token';
|
|
|
33
34
|
* as a `SameSite=Strict; HttpOnly` cookie on the first page load. Cross-origin pages
|
|
34
35
|
* cannot obtain or send this cookie, so their requests are rejected.
|
|
35
36
|
*
|
|
37
|
+
* The cookie is *bootstrapped* for every HTTP request (via {@link expressMiddleware}) so that
|
|
38
|
+
* browsers always receive it, but HTTP requests are only *rejected* on routes that opt in to
|
|
39
|
+
* enforcement via {@link validateRequest} (see {@link HttpConnectionValidator}). WebSocket
|
|
40
|
+
* upgrades are always validated (see {@link allowWsUpgrade}).
|
|
41
|
+
*
|
|
36
42
|
* This complements the origin validator: non-browser callers that omit the Origin
|
|
37
43
|
* header (e.g. Node.js scripts) still cannot reach the backend without the cookie.
|
|
38
44
|
*
|
|
@@ -67,6 +73,24 @@ let BrowserConnectionTokenBackendContribution = class BrowserConnectionTokenBack
|
|
|
67
73
|
// because it is set on the initial page load.
|
|
68
74
|
return false;
|
|
69
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Reject the request with `403` unless it carries a valid connection-token cookie.
|
|
78
|
+
* Always allows the request in Electron deployments, consistent with {@link allowWsUpgrade}.
|
|
79
|
+
*/
|
|
80
|
+
validateRequest(req, res, next) {
|
|
81
|
+
if (index_1.environment.electron.is()) {
|
|
82
|
+
next();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const token = this.getTokenFromCookie(req);
|
|
86
|
+
if (token && this.isTokenValid(token)) {
|
|
87
|
+
next();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// No cookie or stale/invalid token: reject. Legitimate browsers always have the cookie
|
|
91
|
+
// because it is set on the initial page load, and same-origin requests send it automatically.
|
|
92
|
+
res.sendStatus(403);
|
|
93
|
+
}
|
|
70
94
|
expressMiddleware(req, res, next) {
|
|
71
95
|
const existing = this.getTokenFromCookie(req);
|
|
72
96
|
if (!existing || !this.isTokenValid(existing)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-connection-token.js","sourceRoot":"","sources":["../../../src/node/hosting/browser-connection-token.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;
|
|
1
|
+
{"version":3,"file":"browser-connection-token.js","sourceRoot":"","sources":["../../../src/node/hosting/browser-connection-token.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
const chai_1 = require("chai");
|
|
19
|
+
const common_1 = require("../../common");
|
|
19
20
|
const browser_connection_token_1 = require("./browser-connection-token");
|
|
20
21
|
describe('BrowserConnectionToken', () => {
|
|
21
22
|
it('should generate unique tokens', () => {
|
|
@@ -124,5 +125,74 @@ describe('BrowserConnectionTokenBackendContribution', () => {
|
|
|
124
125
|
(0, chai_1.expect)(result.cookieCalls[0].value).to.equal(token.value);
|
|
125
126
|
});
|
|
126
127
|
});
|
|
128
|
+
describe('validateRequest (HTTP token enforcement)', () => {
|
|
129
|
+
function callValidate(cookieValue) {
|
|
130
|
+
const contribution = createContribution();
|
|
131
|
+
const result = { nextCalled: false };
|
|
132
|
+
const req = { headers: {} };
|
|
133
|
+
if (cookieValue !== undefined) {
|
|
134
|
+
req.headers.cookie = `${browser_connection_token_1.BROWSER_TOKEN_COOKIE_NAME}=${cookieValue}`;
|
|
135
|
+
}
|
|
136
|
+
const res = {
|
|
137
|
+
sendStatus: (status) => { result.sentStatus = status; }
|
|
138
|
+
};
|
|
139
|
+
const next = () => { result.nextCalled = true; };
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
141
|
+
contribution.validateRequest(req, res, next);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
it('should allow request with valid token cookie', () => {
|
|
145
|
+
const result = callValidate(token.value);
|
|
146
|
+
(0, chai_1.expect)(result.nextCalled).to.be.true;
|
|
147
|
+
(0, chai_1.expect)(result.sentStatus).to.be.undefined;
|
|
148
|
+
});
|
|
149
|
+
it('should reject request with no cookie', () => {
|
|
150
|
+
const result = callValidate();
|
|
151
|
+
(0, chai_1.expect)(result.nextCalled).to.be.false;
|
|
152
|
+
(0, chai_1.expect)(result.sentStatus).to.equal(403);
|
|
153
|
+
});
|
|
154
|
+
it('should reject request with invalid token', () => {
|
|
155
|
+
const result = callValidate('wrong-token');
|
|
156
|
+
(0, chai_1.expect)(result.nextCalled).to.be.false;
|
|
157
|
+
(0, chai_1.expect)(result.sentStatus).to.equal(403);
|
|
158
|
+
});
|
|
159
|
+
it('should reject request with stale token from previous server', () => {
|
|
160
|
+
const staleToken = (0, browser_connection_token_1.createBrowserConnectionToken)().value;
|
|
161
|
+
const result = callValidate(staleToken);
|
|
162
|
+
(0, chai_1.expect)(result.nextCalled).to.be.false;
|
|
163
|
+
(0, chai_1.expect)(result.sentStatus).to.equal(403);
|
|
164
|
+
});
|
|
165
|
+
it('should reject request with empty token', () => {
|
|
166
|
+
const result = callValidate('');
|
|
167
|
+
(0, chai_1.expect)(result.nextCalled).to.be.false;
|
|
168
|
+
(0, chai_1.expect)(result.sentStatus).to.equal(403);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
describe('Electron deployment (no-op)', () => {
|
|
172
|
+
let originalIsElectron;
|
|
173
|
+
beforeEach(() => {
|
|
174
|
+
originalIsElectron = common_1.environment.electron.is;
|
|
175
|
+
common_1.environment.electron.is = () => true;
|
|
176
|
+
});
|
|
177
|
+
afterEach(() => {
|
|
178
|
+
common_1.environment.electron.is = originalIsElectron;
|
|
179
|
+
});
|
|
180
|
+
it('validateRequest should call next() without a cookie', () => {
|
|
181
|
+
const contribution = createContribution();
|
|
182
|
+
let nextCalled = false;
|
|
183
|
+
let sentStatus;
|
|
184
|
+
const req = { headers: {} };
|
|
185
|
+
const res = { sendStatus: (status) => { sentStatus = status; } };
|
|
186
|
+
const next = () => { nextCalled = true; };
|
|
187
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
188
|
+
contribution.validateRequest(req, res, next);
|
|
189
|
+
(0, chai_1.expect)(nextCalled).to.be.true;
|
|
190
|
+
(0, chai_1.expect)(sentStatus).to.be.undefined;
|
|
191
|
+
});
|
|
192
|
+
it('allowWsUpgrade should return true without a cookie', () => {
|
|
193
|
+
const contribution = createContribution();
|
|
194
|
+
(0, chai_1.expect)(contribution.allowWsUpgrade(createRequest())).to.be.true;
|
|
195
|
+
});
|
|
196
|
+
});
|
|
127
197
|
});
|
|
128
198
|
//# sourceMappingURL=browser-connection-token.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-connection-token.spec.js","sourceRoot":"","sources":["../../../src/node/hosting/browser-connection-token.spec.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browser-connection-token.spec.js","sourceRoot":"","sources":["../../../src/node/hosting/browser-connection-token.spec.ts"],"names":[],"mappings":"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"}
|
package/lib/node/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ export * from './cli';
|
|
|
7
7
|
export * from './setting-service';
|
|
8
8
|
export { FileSystemLocking } from './filesystem-locking';
|
|
9
9
|
export { BackendRequestAllowedContribution } from './request/backend-request-facade';
|
|
10
|
+
export { HttpConnectionValidator } from './hosting/browser-connection-token';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC"}
|
package/lib/node/index.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.BackendRequestAllowedContribution = exports.FileSystemLocking = void 0;
|
|
18
|
+
exports.HttpConnectionValidator = exports.BackendRequestAllowedContribution = exports.FileSystemLocking = void 0;
|
|
19
19
|
const tslib_1 = require("tslib");
|
|
20
20
|
tslib_1.__exportStar(require("./backend-application"), exports);
|
|
21
21
|
tslib_1.__exportStar(require("./backend-global"), exports);
|
|
@@ -28,4 +28,6 @@ var filesystem_locking_1 = require("./filesystem-locking");
|
|
|
28
28
|
Object.defineProperty(exports, "FileSystemLocking", { enumerable: true, get: function () { return filesystem_locking_1.FileSystemLocking; } });
|
|
29
29
|
var backend_request_facade_1 = require("./request/backend-request-facade");
|
|
30
30
|
Object.defineProperty(exports, "BackendRequestAllowedContribution", { enumerable: true, get: function () { return backend_request_facade_1.BackendRequestAllowedContribution; } });
|
|
31
|
+
var browser_connection_token_1 = require("./hosting/browser-connection-token");
|
|
32
|
+
Object.defineProperty(exports, "HttpConnectionValidator", { enumerable: true, get: function () { return browser_connection_token_1.HttpConnectionValidator; } });
|
|
31
33
|
//# sourceMappingURL=index.js.map
|
package/lib/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,gEAAsC;AACtC,2DAAiC;AACjC,kDAAwB;AACxB,6DAAmC;AACnC,sDAA4B;AAC5B,gDAAsB;AACtB,4DAAkC;AAClC,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,2EAAqF;AAA5E,2IAAA,iCAAiC,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,gEAAsC;AACtC,2DAAiC;AACjC,kDAAwB;AACxB,6DAAmC;AACnC,sDAA4B;AAC5B,gDAAsB;AACtB,4DAAkC;AAClC,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,2EAAqF;AAA5E,2IAAA,iCAAiC,OAAA;AAC1C,+EAA6E;AAApE,mIAAA,uBAAuB,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/core",
|
|
3
|
-
"version": "1.74.0-next.
|
|
3
|
+
"version": "1.74.0-next.51+bb9fc73ef",
|
|
4
4
|
"description": "Theia is a cloud & desktop IDE framework implemented in TypeScript.",
|
|
5
5
|
"main": "lib/common/index.js",
|
|
6
6
|
"typings": "lib/common/index.d.ts",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"@lumino/virtualdom": "^2.0.4",
|
|
18
18
|
"@lumino/widgets": "2.7.5",
|
|
19
19
|
"@parcel/watcher": "^2.5.6",
|
|
20
|
-
"@theia/application-package": "1.74.0-next.
|
|
21
|
-
"@theia/request": "1.74.0-next.
|
|
20
|
+
"@theia/application-package": "1.74.0-next.51+bb9fc73ef",
|
|
21
|
+
"@theia/request": "1.74.0-next.51+bb9fc73ef",
|
|
22
22
|
"@types/body-parser": "^1.19.6",
|
|
23
23
|
"@types/express": "^4.17.25",
|
|
24
24
|
"@types/fs-extra": "^4.0.15",
|
|
@@ -230,5 +230,5 @@
|
|
|
230
230
|
"nyc": {
|
|
231
231
|
"extends": "../../configs/nyc.json"
|
|
232
232
|
},
|
|
233
|
-
"gitHead": "
|
|
233
|
+
"gitHead": "bb9fc73ef01cc1add76946df2597681888f6199b"
|
|
234
234
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource GmbH and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { expect } from 'chai';
|
|
18
|
+
import { Container } from 'inversify';
|
|
19
|
+
import electronBackendHostingModule from './electron-backend-hosting-module';
|
|
20
|
+
import { HttpConnectionValidator } from '../../node/hosting/browser-connection-token';
|
|
21
|
+
|
|
22
|
+
describe('electron-backend-hosting-module', () => {
|
|
23
|
+
|
|
24
|
+
it('should bind a no-op HttpConnectionValidator that calls next() unconditionally', () => {
|
|
25
|
+
const container = new Container();
|
|
26
|
+
container.load(electronBackendHostingModule);
|
|
27
|
+
const validator = container.get<HttpConnectionValidator>(HttpConnectionValidator);
|
|
28
|
+
|
|
29
|
+
let nextCalled = false;
|
|
30
|
+
let sentStatus: number | undefined;
|
|
31
|
+
// No cookie provided: the no-op validator must still call next() and never send a status.
|
|
32
|
+
const req = { headers: {} as Record<string, string | undefined> };
|
|
33
|
+
const res = { sendStatus: (status: number) => { sentStatus = status; } };
|
|
34
|
+
const next = (): void => { nextCalled = true; };
|
|
35
|
+
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
validator.validateRequest(req as any, res as any, next as any);
|
|
38
|
+
|
|
39
|
+
expect(nextCalled).to.be.true;
|
|
40
|
+
expect(sentStatus).to.be.undefined;
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -16,9 +16,17 @@
|
|
|
16
16
|
|
|
17
17
|
import { ContainerModule } from 'inversify';
|
|
18
18
|
import { WsRequestValidatorContribution } from '../../node/ws-request-validators';
|
|
19
|
+
import { HttpConnectionValidator } from '../../node/hosting/browser-connection-token';
|
|
19
20
|
import { ElectronWsOriginValidator } from './electron-ws-origin-validator';
|
|
20
21
|
|
|
21
22
|
export default new ContainerModule(bind => {
|
|
22
23
|
bind(ElectronWsOriginValidator).toSelf().inSingletonScope();
|
|
23
24
|
bind(WsRequestValidatorContribution).toService(ElectronWsOriginValidator);
|
|
25
|
+
|
|
26
|
+
// Electron uses its own `ElectronSecurityToken`, so the connection-token cookie is not used.
|
|
27
|
+
// Bind a no-op validator so consumers can inject it uniformly.
|
|
28
|
+
const noopValidator: HttpConnectionValidator = {
|
|
29
|
+
validateRequest: (_req, _res, next) => next()
|
|
30
|
+
};
|
|
31
|
+
bind(HttpConnectionValidator).toConstantValue(noopValidator);
|
|
24
32
|
});
|
|
@@ -19,7 +19,7 @@ import { BackendApplicationContribution } from '../backend-application';
|
|
|
19
19
|
import { WsRequestValidatorContribution } from '../ws-request-validators';
|
|
20
20
|
import { BackendApplicationHosts } from './backend-application-hosts';
|
|
21
21
|
import {
|
|
22
|
-
BrowserConnectionToken, BrowserConnectionTokenBackendContribution, createBrowserConnectionToken
|
|
22
|
+
BrowserConnectionToken, BrowserConnectionTokenBackendContribution, HttpConnectionValidator, createBrowserConnectionToken
|
|
23
23
|
} from './browser-connection-token';
|
|
24
24
|
import { WsOriginValidator } from './ws-origin-validator';
|
|
25
25
|
|
|
@@ -28,9 +28,12 @@ export default new ContainerModule(bind => {
|
|
|
28
28
|
bind(WsOriginValidator).toSelf().inSingletonScope();
|
|
29
29
|
bind(WsRequestValidatorContribution).toService(WsOriginValidator);
|
|
30
30
|
|
|
31
|
-
// Cookie-based connection token
|
|
31
|
+
// Cookie-based connection token. It is validated on WebSocket upgrades and bootstrapped
|
|
32
|
+
// (set as a cookie) on every HTTP request; HTTP enforcement is opt-in per route via
|
|
33
|
+
// `HttpConnectionValidator`.
|
|
32
34
|
bind(BrowserConnectionToken).toConstantValue(createBrowserConnectionToken());
|
|
33
35
|
bind(BrowserConnectionTokenBackendContribution).toSelf().inSingletonScope();
|
|
34
36
|
bind(BackendApplicationContribution).toService(BrowserConnectionTokenBackendContribution);
|
|
35
37
|
bind(WsRequestValidatorContribution).toService(BrowserConnectionTokenBackendContribution);
|
|
38
|
+
bind(HttpConnectionValidator).toService(BrowserConnectionTokenBackendContribution);
|
|
36
39
|
});
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { expect } from 'chai';
|
|
18
18
|
import * as http from 'http';
|
|
19
|
+
import { environment } from '../../common';
|
|
19
20
|
import {
|
|
20
21
|
BrowserConnectionToken,
|
|
21
22
|
BrowserConnectionTokenBackendContribution,
|
|
@@ -164,4 +165,95 @@ describe('BrowserConnectionTokenBackendContribution', () => {
|
|
|
164
165
|
expect(result.cookieCalls[0].value).to.equal(token.value);
|
|
165
166
|
});
|
|
166
167
|
});
|
|
168
|
+
|
|
169
|
+
describe('validateRequest (HTTP token enforcement)', () => {
|
|
170
|
+
|
|
171
|
+
interface ValidationResult {
|
|
172
|
+
nextCalled: boolean;
|
|
173
|
+
sentStatus?: number;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function callValidate(cookieValue?: string): ValidationResult {
|
|
177
|
+
const contribution = createContribution();
|
|
178
|
+
const result: ValidationResult = { nextCalled: false };
|
|
179
|
+
|
|
180
|
+
const req = { headers: {} as Record<string, string | undefined> };
|
|
181
|
+
if (cookieValue !== undefined) {
|
|
182
|
+
req.headers.cookie = `${BROWSER_TOKEN_COOKIE_NAME}=${cookieValue}`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const res = {
|
|
186
|
+
sendStatus: (status: number) => { result.sentStatus = status; }
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const next = (): void => { result.nextCalled = true; };
|
|
190
|
+
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
192
|
+
(contribution as any).validateRequest(req, res, next);
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
it('should allow request with valid token cookie', () => {
|
|
197
|
+
const result = callValidate(token.value);
|
|
198
|
+
expect(result.nextCalled).to.be.true;
|
|
199
|
+
expect(result.sentStatus).to.be.undefined;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should reject request with no cookie', () => {
|
|
203
|
+
const result = callValidate();
|
|
204
|
+
expect(result.nextCalled).to.be.false;
|
|
205
|
+
expect(result.sentStatus).to.equal(403);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should reject request with invalid token', () => {
|
|
209
|
+
const result = callValidate('wrong-token');
|
|
210
|
+
expect(result.nextCalled).to.be.false;
|
|
211
|
+
expect(result.sentStatus).to.equal(403);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should reject request with stale token from previous server', () => {
|
|
215
|
+
const staleToken = createBrowserConnectionToken().value;
|
|
216
|
+
const result = callValidate(staleToken);
|
|
217
|
+
expect(result.nextCalled).to.be.false;
|
|
218
|
+
expect(result.sentStatus).to.equal(403);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should reject request with empty token', () => {
|
|
222
|
+
const result = callValidate('');
|
|
223
|
+
expect(result.nextCalled).to.be.false;
|
|
224
|
+
expect(result.sentStatus).to.equal(403);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe('Electron deployment (no-op)', () => {
|
|
229
|
+
|
|
230
|
+
let originalIsElectron: () => boolean;
|
|
231
|
+
|
|
232
|
+
beforeEach(() => {
|
|
233
|
+
originalIsElectron = environment.electron.is;
|
|
234
|
+
environment.electron.is = () => true;
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
afterEach(() => {
|
|
238
|
+
environment.electron.is = originalIsElectron;
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('validateRequest should call next() without a cookie', () => {
|
|
242
|
+
const contribution = createContribution();
|
|
243
|
+
let nextCalled = false;
|
|
244
|
+
let sentStatus: number | undefined;
|
|
245
|
+
const req = { headers: {} as Record<string, string | undefined> };
|
|
246
|
+
const res = { sendStatus: (status: number) => { sentStatus = status; } };
|
|
247
|
+
const next = (): void => { nextCalled = true; };
|
|
248
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
249
|
+
(contribution as any).validateRequest(req, res, next);
|
|
250
|
+
expect(nextCalled).to.be.true;
|
|
251
|
+
expect(sentStatus).to.be.undefined;
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('allowWsUpgrade should return true without a cookie', () => {
|
|
255
|
+
const contribution = createContribution();
|
|
256
|
+
expect(contribution.allowWsUpgrade(createRequest())).to.be.true;
|
|
257
|
+
});
|
|
258
|
+
});
|
|
167
259
|
});
|
|
@@ -33,6 +33,26 @@ export interface BrowserConnectionToken {
|
|
|
33
33
|
value: string;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export const HttpConnectionValidator = Symbol('HttpConnectionValidator');
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Express middleware provider that rejects HTTP requests lacking a valid connection token.
|
|
40
|
+
*
|
|
41
|
+
* The connection-token cookie is only *bootstrapped* globally (see
|
|
42
|
+
* {@link BrowserConnectionTokenBackendContribution}); enforcement is opt-in per route.
|
|
43
|
+
* Security-sensitive HTTP endpoints (e.g. the filesystem upload/download routes) should
|
|
44
|
+
* inject this and apply {@link validateRequest} as route middleware. Non-sensitive routes
|
|
45
|
+
* (the initial HTML page, static assets) must not use it, as they legitimately have no
|
|
46
|
+
* cookie yet on the very first page load.
|
|
47
|
+
*/
|
|
48
|
+
export interface HttpConnectionValidator {
|
|
49
|
+
/**
|
|
50
|
+
* Express middleware that calls `next()` when the request carries a valid connection-token
|
|
51
|
+
* cookie (or when running in Electron) and responds with `403` otherwise.
|
|
52
|
+
*/
|
|
53
|
+
validateRequest(req: express.Request, res: express.Response, next: express.NextFunction): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
36
56
|
/**
|
|
37
57
|
* Validates WebSocket and HTTP requests using a cookie-based connection token.
|
|
38
58
|
*
|
|
@@ -40,13 +60,18 @@ export interface BrowserConnectionToken {
|
|
|
40
60
|
* as a `SameSite=Strict; HttpOnly` cookie on the first page load. Cross-origin pages
|
|
41
61
|
* cannot obtain or send this cookie, so their requests are rejected.
|
|
42
62
|
*
|
|
63
|
+
* The cookie is *bootstrapped* for every HTTP request (via {@link expressMiddleware}) so that
|
|
64
|
+
* browsers always receive it, but HTTP requests are only *rejected* on routes that opt in to
|
|
65
|
+
* enforcement via {@link validateRequest} (see {@link HttpConnectionValidator}). WebSocket
|
|
66
|
+
* upgrades are always validated (see {@link allowWsUpgrade}).
|
|
67
|
+
*
|
|
43
68
|
* This complements the origin validator: non-browser callers that omit the Origin
|
|
44
69
|
* header (e.g. Node.js scripts) still cannot reach the backend without the cookie.
|
|
45
70
|
*
|
|
46
71
|
* Skipped in Electron deployments (which use their own `ElectronSecurityToken`).
|
|
47
72
|
*/
|
|
48
73
|
@injectable()
|
|
49
|
-
export class BrowserConnectionTokenBackendContribution implements BackendApplicationContribution, WsRequestValidatorContribution {
|
|
74
|
+
export class BrowserConnectionTokenBackendContribution implements BackendApplicationContribution, WsRequestValidatorContribution, HttpConnectionValidator {
|
|
50
75
|
|
|
51
76
|
@inject(BrowserConnectionToken)
|
|
52
77
|
protected readonly browserConnectionToken: BrowserConnectionToken;
|
|
@@ -84,6 +109,25 @@ export class BrowserConnectionTokenBackendContribution implements BackendApplica
|
|
|
84
109
|
return false;
|
|
85
110
|
}
|
|
86
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Reject the request with `403` unless it carries a valid connection-token cookie.
|
|
114
|
+
* Always allows the request in Electron deployments, consistent with {@link allowWsUpgrade}.
|
|
115
|
+
*/
|
|
116
|
+
validateRequest(req: express.Request, res: express.Response, next: express.NextFunction): void {
|
|
117
|
+
if (environment.electron.is()) {
|
|
118
|
+
next();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const token = this.getTokenFromCookie(req);
|
|
122
|
+
if (token && this.isTokenValid(token)) {
|
|
123
|
+
next();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// No cookie or stale/invalid token: reject. Legitimate browsers always have the cookie
|
|
127
|
+
// because it is set on the initial page load, and same-origin requests send it automatically.
|
|
128
|
+
res.sendStatus(403);
|
|
129
|
+
}
|
|
130
|
+
|
|
87
131
|
protected expressMiddleware(req: express.Request, res: express.Response, next: express.NextFunction): void {
|
|
88
132
|
const existing = this.getTokenFromCookie(req);
|
|
89
133
|
if (!existing || !this.isTokenValid(existing)) {
|
package/src/node/index.ts
CHANGED
|
@@ -23,3 +23,4 @@ export * from './cli';
|
|
|
23
23
|
export * from './setting-service';
|
|
24
24
|
export { FileSystemLocking } from './filesystem-locking';
|
|
25
25
|
export { BackendRequestAllowedContribution } from './request/backend-request-facade';
|
|
26
|
+
export { HttpConnectionValidator } from './hosting/browser-connection-token';
|