From 6f418661c4d3dab47e74ba653d33c2ed808e1ab0 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 8 Feb 2026 12:50:21 +0100 Subject: [PATCH] Security checks --- src/extension.ts | 96 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 173d0b3..f3c08b5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,9 @@ import * as vscode from "vscode"; import { currentRun, startRun, stopRun } from "./run"; import { startServer, stopServer } from "./server"; +import os from "os"; +import { exec } from "child_process"; +import net from "net"; export function activate(context: vscode.ExtensionContext) { const config = vscode.workspace.getConfiguration("devrun"); @@ -50,14 +53,99 @@ export function activate(context: vscode.ExtensionContext) { ); console.log("dev-run Activated"); + // Security check - Make sure there aren't any malicious servers currently running const autoStart = config.get("autoStartServer"); - if (autoStart) { - startServer(statusBarItem); - console.log("dev-run server auto started!"); - } + canConnect(63780) + .then((canConnect) => { + if (canConnect) { + console.error( + "Unable to start due to another process listening on port 63780", + ); + + console.error("Possible malicious dev-run instance running"); + + vscode.window + .showErrorMessage( + "Possible malicious dev-run instance running", + "Kill the process listening on port 63780", + ) + .then(async (response) => { + if (!response) return; + + if (response === "Kill the process listening on port 63780") { + await killProcessOnPort(63780); + + if (autoStart) { + startServer(statusBarItem); + console.log("dev-run server auto started!"); + } + } + }); + + return; + } + + if (autoStart) { + startServer(statusBarItem); + console.log("dev-run server auto started!"); + } + }) + .catch(() => {}); } export function deactivate() { stopRun(); } + +export function canConnect( + port: number, + host = "127.0.0.1", + timeout = 1000, +): Promise { + return new Promise((resolve) => { + const socket = new net.Socket(); + + socket.setTimeout(timeout); + + socket.once("connect", () => { + socket.destroy(); + resolve(true); + }); + + socket.once("timeout", () => { + socket.destroy(); + resolve(false); + }); + + socket.once("error", () => { + resolve(false); + }); + + socket.connect(port, host); + }); +} + +export function killProcessOnPort(port: number): Promise { + return new Promise((resolve, reject) => { + const platform = os.platform(); + + let cmd: string; + + if (platform === "win32") { + // Windows + cmd = `for /f "tokens=5" %a in ('netstat -ano ^| findstr :${port}') do taskkill /PID %a /F`; + } else { + // macOS / Linux + cmd = `lsof -ti tcp:${port} | xargs kill -9`; + } + + exec(cmd, (error) => { + if (error) { + resolve(); + } else { + resolve(); + } + }); + }); +}