From fceeb5b0df162e97b47894fa958b55b3be00a68e Mon Sep 17 00:00:00 2001 From: Kolega AI Date: Tue, 10 Feb 2026 11:52:59 +0000 Subject: [PATCH] Fix insecure device pairing token generation --- src/infra/device-pairing.ts | 11 ++++++++--- src/infra/node-pairing.ts | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/infra/device-pairing.ts b/src/infra/device-pairing.ts index c2193af3f38cf..b3462089b5704 100644 --- a/src/infra/device-pairing.ts +++ b/src/infra/device-pairing.ts @@ -1,4 +1,4 @@ -import { randomUUID } from "node:crypto"; +import { randomBytes, randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; import { resolveStateDir } from "../config/paths.js"; @@ -231,8 +231,13 @@ function scopesAllow(requested: string[], allowed: string[]): boolean { return requested.every((scope) => allowedSet.has(scope)); } -function newToken() { - return randomUUID().replaceAll("-", ""); +/** + * Generates a cryptographically secure token for device authentication. + * Uses 32 bytes (256 bits) of entropy from crypto.randomBytes(), + * encoded as base64url (URL-safe, no padding). + */ +function newToken(): string { + return randomBytes(32).toString("base64url"); } export async function listDevicePairing(baseDir?: string): Promise { diff --git a/src/infra/node-pairing.ts b/src/infra/node-pairing.ts index 0d1089e82491c..09d957c5abe82 100644 --- a/src/infra/node-pairing.ts +++ b/src/infra/node-pairing.ts @@ -1,4 +1,4 @@ -import { randomUUID } from "node:crypto"; +import { randomBytes, randomUUID } from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; import { resolveStateDir } from "../config/paths.js"; @@ -143,8 +143,13 @@ function normalizeNodeId(nodeId: string) { return nodeId.trim(); } -function newToken() { - return randomUUID().replaceAll("-", ""); +/** + * Generates a cryptographically secure token for node authentication. + * Uses 32 bytes (256 bits) of entropy from crypto.randomBytes(), + * encoded as base64url (URL-safe, no padding). + */ +function newToken(): string { + return randomBytes(32).toString("base64url"); } export async function listNodePairing(baseDir?: string): Promise {