-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Only allow http request from Electron's own browser-window. Token is generated within electron-main, which also sets it as a cookie within browser-windows. Token is passed to the backend via environment variables. The backend is looking for this specific token to authorize requests. Fixes https://bugs.eclipse.org/bugs/show_bug.cgi?id=551747 Signed-off-by: Paul Maréchal <paul.marechal@ericsson.com>
- Loading branch information
1 parent
68e8e24
commit b212d07
Showing
11 changed files
with
257 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2020 Ericsson and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
/** | ||
* This token is unique the the current running instance. It is used by the backend | ||
* to make sure it is an electron browser window that is connecting to its services. | ||
* | ||
* The identifier is a string, which makes it usable as a key for cookies or similar. | ||
*/ | ||
export const ElectronSecurityToken = 'x-theia-electron-token'; | ||
export interface ElectronSecurityToken { | ||
value: string; | ||
}; |
48 changes: 48 additions & 0 deletions
48
packages/core/src/electron-node/token/electron-token-backend-contribution.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2020 Ericsson and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import express = require('express'); | ||
import { injectable, inject } from 'inversify'; | ||
import { BackendApplicationContribution } from '../../node'; | ||
import { ElectronTokenValidator } from './electron-token-validator'; | ||
|
||
/** | ||
* This component contributes an Express middleware that will refuse all | ||
* requests that do not include a specific token. | ||
*/ | ||
@injectable() | ||
export class ElectronTokenBackendContribution implements BackendApplicationContribution { | ||
|
||
@inject(ElectronTokenValidator) | ||
protected readonly tokenValidator: ElectronTokenValidator; | ||
|
||
configure(app: express.Application): void { | ||
app.use(this.expressMiddleware.bind(this)); | ||
} | ||
|
||
/** | ||
* Only allow token-bearers. | ||
*/ | ||
protected expressMiddleware(req: express.Request, res: express.Response, next: express.NextFunction): void { | ||
if (this.tokenValidator.allowRequest(req)) { | ||
next(); | ||
} else { | ||
console.error(`refused an http request: ${req.connection.remoteAddress}`); | ||
res.sendStatus(403); | ||
} | ||
} | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
packages/core/src/electron-node/token/electron-token-backend-module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2020 Ericsson and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import { ContainerModule } from 'inversify'; | ||
import { BackendApplicationContribution, MessagingService } from '../../node'; | ||
import { MessagingContribution } from '../../node/messaging/messaging-contribution'; | ||
import { ElectronTokenBackendContribution } from './electron-token-backend-contribution'; | ||
import { ElectronMessagingContribution } from './electron-token-messaging-contribution'; | ||
import { ElectronTokenValidator } from './electron-token-validator'; | ||
|
||
export default new ContainerModule((bind, unbind, isBound, rebind) => { | ||
bind<ElectronTokenValidator>(ElectronTokenValidator).toSelf().inSingletonScope(); | ||
|
||
bind<ElectronTokenBackendContribution>(ElectronTokenBackendContribution).toSelf().inSingletonScope(); | ||
bind<BackendApplicationContribution>(BackendApplicationContribution).toService(ElectronTokenBackendContribution); | ||
|
||
rebind<MessagingContribution>(MessagingService.Identifier).to(ElectronMessagingContribution).inSingletonScope(); | ||
}); |
44 changes: 44 additions & 0 deletions
44
packages/core/src/electron-node/token/electron-token-messaging-contribution.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2020 Ericsson and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import * as net from 'net'; | ||
import * as http from 'http'; | ||
import { injectable, inject } from 'inversify'; | ||
import { MessagingContribution } from '../../node/messaging/messaging-contribution'; | ||
import { ElectronTokenValidator } from './electron-token-validator'; | ||
|
||
/** | ||
* Override the browser MessagingContribution class to refuse connections that do not include a specific token. | ||
*/ | ||
@injectable() | ||
export class ElectronMessagingContribution extends MessagingContribution { | ||
|
||
@inject(ElectronTokenValidator) | ||
protected readonly tokenValidator: ElectronTokenValidator; | ||
|
||
/** | ||
* Only allow token-bearers. | ||
*/ | ||
protected handleHttpUpgrade(request: http.IncomingMessage, socket: net.Socket, head: Buffer): void { | ||
if (this.tokenValidator.allowRequest(request)) { | ||
super.handleHttpUpgrade(request, socket, head); | ||
} else { | ||
console.error(`refused a websocket connection: ${request.connection.remoteAddress}`); | ||
socket.destroy(); // kill connection, client will take that as a "no". | ||
} | ||
} | ||
|
||
} |
55 changes: 55 additions & 0 deletions
55
packages/core/src/electron-node/token/electron-token-validator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2020 Ericsson and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import * as http from 'http'; | ||
import * as cookie from 'cookie'; | ||
import { injectable } from 'inversify'; | ||
import { ElectronSecurityToken } from '../../electron-common/electron-token'; | ||
|
||
/** | ||
* On Electron, we want to make sure that only Electron's browser-windows access the backend services. | ||
*/ | ||
@injectable() | ||
export class ElectronTokenValidator { | ||
|
||
protected electronSecurityToken: ElectronSecurityToken = this.getToken(); | ||
|
||
/** | ||
* Expects the token to be passed via cookies by default. | ||
*/ | ||
allowRequest(request: http.IncomingMessage): boolean { | ||
const cookieHeader = request.headers.cookie; | ||
if (typeof cookieHeader === 'string') { | ||
const token = cookie.parse(cookieHeader)[ElectronSecurityToken]; | ||
if (typeof token === 'string') { | ||
return this.isTokenValid(JSON.parse(token)); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
isTokenValid(token: ElectronSecurityToken): boolean { | ||
return typeof token === 'object' && token.value === this.electronSecurityToken!.value; | ||
} | ||
|
||
/** | ||
* Returns the token to compare to when authorizing requests. | ||
*/ | ||
protected getToken(): ElectronSecurityToken { | ||
return JSON.parse(process.env[ElectronSecurityToken]!); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.