Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit 8a491ed

Browse files
elektronikworkshopadiazulay
authored andcommitted
Fixed security issue
* Web-server for library-, board-manager etc. was not listening on localhost but on the machine's main interface * Web-server wasn't launched asynchronously what can cause problems * Port was stored redundantly in webserver class Addresses #966
1 parent 5f32221 commit 8a491ed

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

src/arduino/arduinoContentProvider.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@ export class ArduinoContentProvider implements vscode.TextDocumentContentProvide
1616
private _webserver: LocalWebServer;
1717
private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
1818

19-
constructor(
20-
private _extensionPath: string) {
21-
this.initialize();
22-
}
19+
constructor(private _extensionPath: string) { }
2320

24-
public initialize() {
21+
public async initialize() {
2522
this._webserver = new LocalWebServer(this._extensionPath);
2623
// Arduino Boards Manager
2724
this.addHandlerWithLogger("show-boardmanager", "/boardmanager", (req, res) => this.getHtmlView(req, res));
@@ -50,7 +47,7 @@ export class ArduinoContentProvider implements vscode.TextDocumentContentProvide
5047
this.addHandlerWithLogger("load-examples", "/api/examples", async (req, res) => await this.getExamples(req, res));
5148
this.addHandlerWithLogger("open-example", "/api/openexample", (req, res) => this.openExample(req, res), true);
5249

53-
this._webserver.start();
50+
await this._webserver.start();
5451
}
5552

5653
public async provideTextDocumentContent(uri: vscode.Uri): Promise<string> {

src/arduino/localWebServer.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import * as path from "path";
99
export default class LocalWebServer {
1010
private app = express();
1111
private server;
12-
private _serverPort: string;
1312

1413
constructor(private _extensionPath: string) {
1514
this.app.use("/", express.static(path.join(this._extensionPath, "./out/views")));
@@ -18,10 +17,10 @@ export default class LocalWebServer {
1817
}
1918

2019
public getServerUrl(): string {
21-
return `http://localhost:${this._serverPort}`;
20+
return `http://localhost:${this.server.address().port}`;
2221
}
2322
public getEndpointUri(type: string): string {
24-
return `http://localhost:${this._serverPort}/${type}`;
23+
return `http://localhost:${this.server.address().port}/${type}`;
2524
}
2625

2726
public addHandler(url: string, handler: (req, res) => void): void {
@@ -32,10 +31,24 @@ export default class LocalWebServer {
3231
this.app.post(url, handler);
3332
}
3433

35-
public start(): void {
36-
const port = this.server.listen(0).address().port;
37-
// tslint:disable-next-line
38-
console.log(`Starting express server on port: ${port}`);
39-
this._serverPort = port;
34+
/**
35+
* Start webserver.
36+
* If it fails to listen reject will report its error.
37+
*/
38+
public async start() {
39+
return new Promise<void>((resolve, reject) => {
40+
// Address and port are available as soon as the server
41+
// started listening, resolving localhost requires
42+
// some time.
43+
this.server.listen(0, "localhost", (error) => {
44+
if (error) {
45+
reject(error);
46+
return;
47+
}
48+
// tslint:disable-next-line
49+
console.log(`Express server listening on port: ${this.server.address().port}`);
50+
resolve();
51+
});
52+
});
4053
}
4154
}

src/extension.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,10 @@ export async function activate(context: vscode.ExtensionContext) {
333333
}
334334
Logger.traceUserData("end-activate-extension", { correlationId: activeGuid });
335335

336-
setTimeout(() => {
336+
setTimeout(async () => {
337337
const arduinoManagerProvider = new arduinoContentProviderModule.ArduinoContentProvider(context.extensionPath);
338+
await arduinoManagerProvider.initialize();
339+
338340
context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(ARDUINO_MANAGER_PROTOCOL, arduinoManagerProvider));
339341
registerArduinoCommand("arduino.showBoardManager", async () => {
340342
const panel = vscode.window.createWebviewPanel("arduinoBoardManager", "Arduino Board Manager", vscode.ViewColumn.Two, {

0 commit comments

Comments
 (0)