chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:39:12 +08:00
commit d8dcd5f6d1
8604 changed files with 2479390 additions and 0 deletions
@@ -0,0 +1,49 @@
/**
* Regression: when OMNIROUTE_BUILD_PROFILE=minimal is the resolved build
* profile, the four stub modules throw FeatureDisabledError instead of
* performing their privileged operations.
* See docs/security/SOCKET_DEV_FINDINGS.md.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
test("featureDisabledError carries the featureName", async () => {
const mod = await import("../../../src/lib/build-profile/featureDisabled.ts");
const err = mod.featureDisabledError("my-feature");
assert.equal(err.featureName, "my-feature");
assert.match(err.message, /my-feature/);
assert.match(err.message, /minimal/);
assert.equal("OMNIROUTE_BUILD_PROFILE" in mod, false);
assert.equal("IS_MINIMAL_BUILD" in mod, false);
});
test("install.stub.ts: installCert / uninstallCert throw FeatureDisabledError", async () => {
const stub = await import("../../../src/mitm/cert/install.stub.ts");
await assert.rejects(() => stub.installCert("pw", "/tmp/x"), /mitm-cert-install/);
await assert.rejects(() => stub.uninstallCert("pw", "/tmp/x"), /mitm-cert-install/);
// checkCertInstalled returns false (does not throw — used by render paths)
assert.equal(await stub.checkCertInstalled("/tmp/x"), false);
});
test("keychain-reader.stub.ts: discoverZedCredentials / getZedCredential throw", async () => {
const stub = await import("../../../src/lib/zed-oauth/keychain-reader.stub.ts");
await assert.rejects(() => stub.discoverZedCredentials(), /zed-keychain-import/);
await assert.rejects(() => stub.getZedCredential("openai"), /zed-keychain-import/);
assert.equal(await stub.isZedInstalled(), false);
});
test("cloudSync.stub.ts: syncToCloud soft-fails with feature-disabled message", async () => {
const stub = await import("../../../src/lib/cloudSync.stub.ts");
const result = await stub.syncToCloud("machine-id");
assert.deepEqual(result, {
error: "Cloud Sync is disabled in this build (minimal profile)",
});
assert.equal(stub.CLOUD_SYNC_SECRETS_ENABLED, false);
await assert.rejects(() => stub.fetchWithTimeout(), /cloud-sync/);
});
test("ninerouter.stub.ts: install / resolveSpawnArgs throw FeatureDisabledError", async () => {
const stub = await import("../../../src/lib/services/installers/ninerouter.stub.ts");
await assert.rejects(() => stub.installNinerouter(), /9router-installer/);
assert.throws(() => stub.resolveSpawnArgs("api-key", 20130), /9router-installer/);
});
@@ -0,0 +1,51 @@
/**
* Regression: Cloud sync must verify the X-Cloud-Sig HMAC and must NOT
* overwrite accessToken / refreshToken unless OMNIROUTE_CLOUD_SYNC_SECRETS=true.
* See docs/security/SOCKET_DEV_FINDINGS.md §5.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
import crypto from "node:crypto";
test("verifyCloudSignature accepts a valid HMAC", async () => {
// Test-only HMAC key derived deterministically — no hardcoded production secret.
const TEST_HMAC_KEY = crypto.createHash("sha256").update("omniroute-test").digest("hex");
process.env.OMNIROUTE_CLOUD_SYNC_SECRET = TEST_HMAC_KEY;
// Re-import so the module re-reads the env.
const mod = await import(
"../../../src/lib/cloudSync.ts?cache=" + Date.now()
).catch(() => import("../../../src/lib/cloudSync.ts"));
const body = JSON.stringify({ data: { providers: {} } });
const sig = crypto.createHmac("sha256", TEST_HMAC_KEY).update(body).digest("hex");
assert.equal((mod as any).verifyCloudSignature(body, sig), true);
});
test("verifyCloudSignature rejects a forged signature", async () => {
// Test-only HMAC key derived deterministically — no hardcoded production secret.
const TEST_HMAC_KEY = crypto.createHash("sha256").update("omniroute-test").digest("hex");
process.env.OMNIROUTE_CLOUD_SYNC_SECRET = TEST_HMAC_KEY;
const mod = await import("../../../src/lib/cloudSync.ts");
const body = JSON.stringify({ data: { providers: {} } });
const forged = "0".repeat(64);
assert.equal((mod as any).verifyCloudSignature(body, forged), false);
});
test("verifyCloudSignature rejects when the secret is set but sig header is missing", async () => {
// Test-only HMAC key derived deterministically — no hardcoded production secret.
const TEST_HMAC_KEY = crypto.createHash("sha256").update("omniroute-test").digest("hex");
process.env.OMNIROUTE_CLOUD_SYNC_SECRET = TEST_HMAC_KEY;
const mod = await import("../../../src/lib/cloudSync.ts");
const body = JSON.stringify({ data: { providers: {} } });
assert.equal((mod as any).verifyCloudSignature(body, null), false);
});
test("verifyCloudSignature falls through (legacy mode) when secret is unset", async () => {
delete process.env.OMNIROUTE_CLOUD_SYNC_SECRET;
// Force re-import so module constants pick up the cleared env.
delete (globalThis as any).__omniroute_cloudSync_cache;
const mod = await import("../../../src/lib/cloudSync.ts");
const body = JSON.stringify({ data: { providers: {} } });
// Behaviour: accept unsigned body but log warning. We assert it doesn't throw.
const result = (mod as any).verifyCloudSignature(body, null);
assert.equal(typeof result, "boolean");
});
@@ -0,0 +1,52 @@
import test from "node:test";
import assert from "node:assert/strict";
import path from "node:path";
import { resolveSafeI18nSectionDir } from "../../../src/lib/docsI18nPath.ts";
const DOCS_ROOT = path.resolve("/srv/app", "docs");
const I18N_ROOT = path.join(DOCS_ROOT, "i18n");
test("resolveSafeI18nSectionDir rejects traversal in the locale (cookie-controlled)", () => {
const badLocales = ["..", "../..", "/etc", "es/../../etc", "es\0", "..%2f", "en.", "es/x"];
for (const locale of badLocales) {
assert.strictEqual(
resolveSafeI18nSectionDir(DOCS_ROOT, locale, ["overview"]),
null,
`Should reject bad locale: ${JSON.stringify(locale)}`
);
}
});
test("resolveSafeI18nSectionDir rejects traversal in slug segments", () => {
const badSlugs = [[".."], ["..", "foo"], ["/etc", "passwd"], ["foo", "..", "bar"], ["a/b"]];
for (const slug of badSlugs) {
assert.strictEqual(
resolveSafeI18nSectionDir(DOCS_ROOT, "pt-BR", slug),
null,
`Should reject bad slug: ${slug.join("/")}`
);
}
});
test("resolveSafeI18nSectionDir confines the resolved dir to docs/i18n", () => {
// Valid input → a dir strictly under i18nRoot.
const ok = resolveSafeI18nSectionDir(DOCS_ROOT, "pt-BR", ["architecture", "overview"]);
assert.ok(ok, "valid locale+slug should resolve");
assert.ok(
ok === I18N_ROOT || ok.startsWith(I18N_ROOT + path.sep),
`resolved dir must stay under i18nRoot, got ${ok}`
);
assert.strictEqual(ok, path.join(I18N_ROOT, "pt-BR", "docs", "architecture"));
});
test("resolveSafeI18nSectionDir allows valid locale/slug patterns", () => {
const goodLocales = ["en", "pt-BR", "zh-CN", "es"];
for (const locale of goodLocales) {
assert.ok(
resolveSafeI18nSectionDir(DOCS_ROOT, locale, ["getting-started"]),
`Should allow good locale: ${locale}`
);
}
assert.ok(resolveSafeI18nSectionDir(DOCS_ROOT, "es", ["v1-migration"]));
assert.strictEqual(resolveSafeI18nSectionDir(DOCS_ROOT, "es", []), null, "empty slug → null");
});
@@ -0,0 +1,27 @@
import test from "node:test";
import assert from "node:assert/strict";
import { sanitizeDocsHtml } from "../../../src/lib/docsSanitizer.ts";
test("sanitizeDocsHtml removes dangerous tags and attributes", () => {
const malicious = '<script>alert("xss")</script><img src="x" onerror="alert(1)"> <a href="javascript:alert(1)">link</a> <div onclick="evil()">content</div>';
const sanitized = sanitizeDocsHtml(malicious);
assert.ok(!sanitized.includes("<script>"), "Should remove <script>");
assert.ok(!sanitized.includes("onerror"), "Should remove onerror");
assert.ok(!sanitized.includes("onclick"), "Should remove onclick");
assert.ok(!sanitized.includes("javascript:"), "Should remove javascript: URLs");
assert.ok(sanitized.includes("<a>link</a>") || sanitized.includes("<a >link</a>") || sanitized.includes("link"), "Should keep safe content");
});
test("sanitizeDocsHtml allows safe tags and attributes", () => {
const safe = '<h1>Title</h1><p>Paragraph with <strong>bold</strong> and <em>italic</em>.</p><ul><li>Item</li></ul><pre><code>code</code></pre>';
const sanitized = sanitizeDocsHtml(safe);
assert.ok(sanitized.includes("<h1>Title</h1>"), "Should allow <h1>");
assert.ok(sanitized.includes("<p>"), "Should allow <p>");
assert.ok(sanitized.includes("<strong>"), "Should allow <strong>");
assert.ok(sanitized.includes("<ul>"), "Should allow <ul>");
assert.ok(sanitized.includes("<li>"), "Should allow <li>");
assert.ok(sanitized.includes("<pre>"), "Should allow <pre>");
assert.ok(sanitized.includes("<code>"), "Should allow <code>");
});
@@ -0,0 +1,87 @@
/**
* Regression: runElevatedPowerShell() must no longer use -EncodedCommand and
* must write the elevated payload to a per-call temp .ps1 file referenced via
* -File. See docs/security/SOCKET_DEV_FINDINGS.md §1.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
import os from "node:os";
import fs from "node:fs";
import path from "node:path";
import {
buildElevatedScriptWrapper,
_runElevatedPowerShellForTest,
} from "../../../src/mitm/systemCommands.ts";
test("buildElevatedScriptWrapper does not contain -EncodedCommand fingerprint", () => {
const wrapper = buildElevatedScriptWrapper("C:\\Temp\\omniroute-elevate-x.ps1");
assert.ok(
!wrapper.includes("-EncodedCommand"),
"wrapper must not contain -EncodedCommand (Socket.dev textbook fingerprint)"
);
assert.ok(wrapper.includes("-File"), "wrapper must reference the payload via -File");
assert.ok(wrapper.includes("Start-Process"), "wrapper must use Start-Process -Verb RunAs");
assert.ok(wrapper.includes("-Verb RunAs"), "wrapper must request elevation via -Verb RunAs");
});
test("buildElevatedScriptWrapper quotes the script path safely (no shell injection)", () => {
const wrapper = buildElevatedScriptWrapper("C:\\Temp\\path with spaces'and-quote.ps1");
// PowerShell single-quote escaping doubles the quote — our quotePowerShell
// helper does that. Confirm both the original and the escaped form are present.
assert.ok(
wrapper.includes("'C:\\Temp\\path with spaces''and-quote.ps1'"),
"single quotes in the path must be doubled per PowerShell escaping rules"
);
});
test("_runElevatedPowerShellForTest writes payload to a temp .ps1 file and unlinks after", async () => {
let capturedWrapper: string | null = null;
let capturedTempPath: string | null = null;
await _runElevatedPowerShellForTest(
"Write-Output 'omniroute regression test'",
async (wrapper, tempPath) => {
capturedWrapper = wrapper;
capturedTempPath = tempPath;
assert.ok(fs.existsSync(tempPath), "temp file must exist while the runner is active");
const content = fs.readFileSync(tempPath, "utf8");
assert.match(content, /Write-Output 'omniroute regression test'/);
return "ok";
}
);
assert.ok(capturedWrapper, "wrapper must be captured");
assert.ok(!capturedWrapper!.includes("-EncodedCommand"), "wrapper must not use -EncodedCommand");
assert.ok(capturedTempPath, "temp path must be captured");
assert.ok(
capturedTempPath!.startsWith(path.resolve(os.tmpdir())) ||
capturedTempPath!.startsWith(os.tmpdir()),
"temp .ps1 must live inside os.tmpdir()"
);
assert.ok(
!fs.existsSync(capturedTempPath!),
"temp .ps1 file must be unlinked after the runner returns"
);
});
test("_runElevatedPowerShellForTest unlinks the temp file even when the runner throws", async () => {
let capturedTempPath: string | null = null;
let threw = false;
try {
await _runElevatedPowerShellForTest("Write-Output 'denied'", async (_wrapper, tempPath) => {
capturedTempPath = tempPath;
throw new Error("simulated UAC denial");
});
} catch (err) {
threw = true;
assert.match((err as Error).message, /simulated UAC denial/);
}
assert.ok(threw, "the error must propagate to the caller");
assert.ok(capturedTempPath, "temp path must still be captured");
assert.ok(
!fs.existsSync(capturedTempPath!),
"temp .ps1 must be removed by the finally block even after a failed call"
);
});
@@ -0,0 +1,177 @@
/**
* Unit tests for `liveServerAllowList`.
*
* Bug #1 (plans/2026-06-23-omniroute-v3.8.34-deep-audit.md) introduced the
* `LIVE_WS_ALLOWED_HOSTS` opt-in for LAN/Tailscale deployments. These tests
* pin down the contract: defaults remain loopback-only; the env var extends
* the allow-list with bare hostnames or `host:port` pairs; the absence of
* Origin is still only acceptable on loopback.
*
* Runner note: lives under tests/unit/security/ (a node:testcollected subdir)
* and uses node:test + assert/strict so the gate `check:test-discovery` actually
* runs it. The original copy under tests/unit/server/ used vitest in a path no
* runner collected — it never executed (caught by Gate 6A.1).
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import {
buildAllowedOrigins,
buildAllowedHosts,
isOriginAllowed,
originHost,
originHostMatches,
parseCsvEnv,
DEFAULT_ALLOWED_ORIGINS,
} from "@/server/ws/liveServerAllowList";
const EMPTY_ENV: NodeJS.ProcessEnv = {};
describe("parseCsvEnv", () => {
it("returns empty set for undefined", () => {
assert.equal(parseCsvEnv(undefined).size, 0);
});
it("returns empty set for empty string", () => {
assert.equal(parseCsvEnv("").size, 0);
});
it("trims whitespace and drops empty entries", () => {
const out = parseCsvEnv(" a , b ,, c ");
assert.deepEqual([...out], ["a", "b", "c"]);
});
it("deduplicates entries", () => {
const out = parseCsvEnv("a,a,b");
assert.deepEqual([...out], ["a", "b"]);
});
});
describe("buildAllowedOrigins", () => {
it("includes the loopback defaults", () => {
const out = buildAllowedOrigins(EMPTY_ENV);
for (const origin of DEFAULT_ALLOWED_ORIGINS) {
assert.equal(out.has(origin), true);
}
});
it("extends defaults with LIVE_WS_ALLOWED_ORIGINS", () => {
const env = {
...EMPTY_ENV,
LIVE_WS_ALLOWED_ORIGINS: "https://dash.example.com,https://other.example.com",
};
const out = buildAllowedOrigins(env);
assert.equal(out.has("https://dash.example.com"), true);
assert.equal(out.has("https://other.example.com"), true);
// Defaults remain.
assert.equal(out.has("http://localhost:20128"), true);
});
});
describe("buildAllowedHosts", () => {
it("returns empty set when env is not set", () => {
assert.equal(buildAllowedHosts(EMPTY_ENV).size, 0);
});
it("parses comma-separated hosts", () => {
const env = { ...EMPTY_ENV, LIVE_WS_ALLOWED_HOSTS: "100.96.135.160,desktop.tailnet.ts.net" };
const out = buildAllowedHosts(env);
assert.equal(out.has("100.96.135.160"), true);
assert.equal(out.has("desktop.tailnet.ts.net"), true);
});
});
describe("originHost", () => {
it("returns host and hostname for a valid URL", () => {
assert.deepEqual(originHost("http://100.96.135.160:20128"), {
host: "100.96.135.160:20128",
hostname: "100.96.135.160",
});
});
it("returns null for an invalid URL", () => {
assert.equal(originHost("not a url"), null);
});
});
describe("originHostMatches", () => {
it("returns false when the allow-list is empty", () => {
assert.equal(originHostMatches("http://100.96.135.160:20128", new Set()), false);
});
it("matches by exact host:port", () => {
const allow = new Set(["100.96.135.160:20128"]);
assert.equal(originHostMatches("http://100.96.135.160:20128", allow), true);
});
it("matches by bare hostname regardless of port", () => {
const allow = new Set(["100.96.135.160"]);
assert.equal(originHostMatches("http://100.96.135.160:20128", allow), true);
assert.equal(originHostMatches("http://100.96.135.160:55555", allow), true);
});
it("returns false for a non-matching host", () => {
const allow = new Set(["100.96.135.160"]);
assert.equal(originHostMatches("http://10.0.0.5:20128", allow), false);
});
it("returns false for an unparseable origin", () => {
const allow = new Set(["100.96.135.160"]);
assert.equal(originHostMatches("not-a-url", allow), false);
});
});
describe("isOriginAllowed", () => {
it("rejects any non-loopback origin by default", () => {
assert.equal(isOriginAllowed("http://100.96.135.160:20128", EMPTY_ENV), false);
});
it("accepts the default loopback origins", () => {
assert.equal(isOriginAllowed("http://127.0.0.1:20128", EMPTY_ENV), true);
assert.equal(isOriginAllowed("http://localhost:20128", EMPTY_ENV), true);
assert.equal(isOriginAllowed("http://[::1]:20128", EMPTY_ENV), true);
});
it("accepts an Origin matching LIVE_WS_ALLOWED_ORIGINS", () => {
const env = { ...EMPTY_ENV, LIVE_WS_ALLOWED_ORIGINS: "https://dash.example.com" };
assert.equal(isOriginAllowed("https://dash.example.com", env), true);
});
it("accepts a Tailscale Origin when LIVE_WS_ALLOWED_HOSTS is set", () => {
const env = { ...EMPTY_ENV, LIVE_WS_ALLOWED_HOSTS: "100.96.135.160" };
assert.equal(isOriginAllowed("http://100.96.135.160:20128", env), true);
});
it("accepts a Tailscale Origin matched by host:port when LIVE_WS_ALLOWED_HOSTS is set", () => {
const env = { ...EMPTY_ENV, LIVE_WS_ALLOWED_HOSTS: "100.96.135.160:20128" };
assert.equal(isOriginAllowed("http://100.96.135.160:20128", env), true);
});
it("does NOT accept a Tailscale Origin when LIVE_WS_ALLOWED_HOSTS is unset", () => {
// Critical security invariant: without explicit opt-in, the LAN/Tailscale
// surface is closed even though the listener is reachable.
assert.equal(isOriginAllowed("http://100.96.135.160:20128", EMPTY_ENV), false);
});
it("rejects a missing Origin when bound to LAN (0.0.0.0)", () => {
// A CLI client that omits Origin should NOT be accepted when the
// operator opted into LAN exposure. Browsers always send Origin, so the
// empty-Origin path is for non-browser callers; the security stance is
// "refuse unless loopback".
const env = { ...EMPTY_ENV, LIVE_WS_HOST: "0.0.0.0" };
assert.equal(isOriginAllowed(undefined, env), false);
});
it("accepts a missing Origin on loopback (CLI/MCP)", () => {
// CLI/MCP clients running on the same host omit Origin. The default
// listener (127.0.0.1) accepts them.
assert.equal(isOriginAllowed(undefined, EMPTY_ENV), true);
});
it("accepts a missing Origin on ::1 / localhost hosts", () => {
const env1 = { ...EMPTY_ENV, LIVE_WS_HOST: "::1" };
assert.equal(isOriginAllowed(undefined, env1), true);
const env2 = { ...EMPTY_ENV, LIVE_WS_HOST: "localhost" };
assert.equal(isOriginAllowed(undefined, env2), true);
});
});
+196
View File
@@ -0,0 +1,196 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import { isLocalRequestAllowed } from "../../../src/lib/security/localEndpoints.ts";
/**
* Tests for the /api/local/* security guard. The guard reads from
* `globalThis.__omniRequestHeaders` (set by the Next.js middleware shim) and
* from `process.env` (production opt-in and bearer token). Each test cleans
* up both before and after running so the order doesn't matter.
*/
type OmniGlobals = { __omniRequestHeaders?: Headers };
const G = globalThis as OmniGlobals;
function reset() {
delete G.__omniRequestHeaders;
}
function setHeaders(headers: Record<string, string>) {
G.__omniRequestHeaders = new Headers(headers);
}
test("isLocalRequestAllowed: allows when no headers injected and not production", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevEnabled = process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED;
delete process.env.NODE_ENV;
delete process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED;
reset();
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, true, `expected allowed, got: ${JSON.stringify(out)}`);
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevEnabled !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED = prevEnabled;
}
});
test("isLocalRequestAllowed: allows loopback host + empty xff (browser dev path)", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevToken = process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
delete process.env.NODE_ENV;
delete process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
setHeaders({ host: "localhost:20128" });
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, true, `expected allowed, got: ${JSON.stringify(out)}`);
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevToken !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = prevToken;
}
});
test("isLocalRequestAllowed: allows IPv4 loopback host 127.0.0.1", () => {
const prevNodeEnv = process.env.NODE_ENV;
delete process.env.NODE_ENV;
setHeaders({ host: "127.0.0.1:20128" });
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, true);
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
}
});
test("isLocalRequestAllowed: allows IPv6 loopback host [::1]", () => {
const prevNodeEnv = process.env.NODE_ENV;
delete process.env.NODE_ENV;
setHeaders({ host: "[::1]:20128" });
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, true);
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
}
});
test("isLocalRequestAllowed: rejects public host even with loopback x-forwarded-for", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevToken = process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
delete process.env.NODE_ENV;
delete process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
// Public Host with loopback XFF is rejected — Host header is the
// authoritative loopback check (defence against Host header injection
// from a tunneled dev URL).
setHeaders({ host: "example.com", "x-forwarded-for": "127.0.0.1" });
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, false);
assert.equal(out.reason, "non-local origin");
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevToken !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = prevToken;
}
});
test("isLocalRequestAllowed: rejects non-loopback origin (no bearer token)", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevToken = process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
delete process.env.NODE_ENV;
delete process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
setHeaders({ host: "example.com", "x-forwarded-for": "203.0.113.5" });
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, false);
assert.equal(out.reason, "non-local origin");
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevToken !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = prevToken;
}
});
test("isLocalRequestAllowed: bearer token takes precedence over host check (desktop app)", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevToken = process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = "s3cret-token-abc";
delete process.env.NODE_ENV;
// Non-loopback origin BUT valid bearer token → allowed (desktop app)
setHeaders({
host: "example.com",
"x-forwarded-for": "203.0.113.5",
authorization: "Bearer s3cret-token-abc",
});
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, true, `expected allowed, got: ${JSON.stringify(out)}`);
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevToken !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = prevToken;
}
});
test("isLocalRequestAllowed: rejects wrong bearer token even with token configured", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevToken = process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN;
process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = "s3cret-token-abc";
delete process.env.NODE_ENV;
setHeaders({
host: "example.com",
"x-forwarded-for": "203.0.113.5",
authorization: "Bearer wrong-token",
});
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, false);
// Falls through to the host check, which rejects.
assert.equal(out.reason, "non-local origin");
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevToken !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_TOKEN = prevToken;
}
});
test("isLocalRequestAllowed: production without opt-in rejects (no headers path)", () => {
const prevNodeEnv = process.env.NODE_ENV;
const prevEnabled = process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED;
process.env.NODE_ENV = "production";
delete process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED;
reset();
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, false);
assert.equal(out.reason, "disabled in production");
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevEnabled !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED = prevEnabled;
}
});
test("isLocalRequestAllowed: production WITH opt-in allows (no headers path)", () => {
// The "no headers" path bypasses the host check entirely; it's the catch-all
// for non-Next contexts (cron jobs, scripts). In production with opt-in,
// the function returns { allowed: true } for that path. This is by design:
// the production gate is at the route handler, not the guard.
const prevNodeEnv = process.env.NODE_ENV;
const prevEnabled = process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED;
process.env.NODE_ENV = "production";
process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED = "1";
reset();
try {
const out = isLocalRequestAllowed();
assert.equal(out.allowed, true);
} finally {
reset();
if (prevNodeEnv !== undefined) process.env.NODE_ENV = prevNodeEnv;
if (prevEnabled !== undefined) process.env.OMNIROUTE_LOCAL_ENDPOINTS_ENABLED = prevEnabled;
}
});
@@ -0,0 +1,37 @@
/**
* Regression: fingerprintZedCredential is deterministic, 16 hex chars, and
* different inputs produce different fingerprints (collision sanity).
* See docs/security/SOCKET_DEV_FINDINGS.md §2.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
import { fingerprintZedCredential } from "../../../src/lib/zed-oauth/credentialFingerprint.ts";
test("fingerprint is 16 lowercase hex chars", () => {
const fp = fingerprintZedCredential("zed-openai", "default", "sk-test-token-1234");
assert.match(fp, /^[0-9a-f]{16}$/);
});
test("fingerprint is deterministic across calls", () => {
const a = fingerprintZedCredential("zed-openai", "default", "sk-test-token-1234");
const b = fingerprintZedCredential("zed-openai", "default", "sk-test-token-1234");
assert.equal(a, b);
});
test("different service produces different fingerprint", () => {
const a = fingerprintZedCredential("zed-openai", "default", "sk-test-token-1234");
const b = fingerprintZedCredential("zed-anthropic", "default", "sk-test-token-1234");
assert.notEqual(a, b);
});
test("different account produces different fingerprint", () => {
const a = fingerprintZedCredential("zed-openai", "default", "sk-test-token-1234");
const b = fingerprintZedCredential("zed-openai", "alt-account", "sk-test-token-1234");
assert.notEqual(a, b);
});
test("different token produces different fingerprint", () => {
const a = fingerprintZedCredential("zed-openai", "default", "sk-test-token-1234");
const b = fingerprintZedCredential("zed-openai", "default", "sk-test-token-other");
assert.notEqual(a, b);
});
@@ -0,0 +1,107 @@
/**
* Regression: confirmedAccounts validation helpers reject malformed bodies and
* filterCredentialsByConfirmation only returns credentials whose fingerprint
* matches a confirmed entry. See docs/security/SOCKET_DEV_FINDINGS.md §2.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
import {
isConfirmedAccount,
parseConfirmedAccounts,
filterCredentialsByConfirmation,
} from "../../../src/lib/zed-oauth/confirmedAccounts.ts";
import { fingerprintZedCredential } from "../../../src/lib/zed-oauth/credentialFingerprint.ts";
test("isConfirmedAccount rejects null / wrong-typed entries", () => {
assert.equal(isConfirmedAccount(null), false);
assert.equal(isConfirmedAccount("string"), false);
assert.equal(isConfirmedAccount({}), false);
assert.equal(isConfirmedAccount({ service: "zed-openai" }), false);
assert.equal(
isConfirmedAccount({ service: "zed-openai", account: "default", fingerprint: "" }),
false
);
assert.equal(
isConfirmedAccount({ service: 123, account: "default", fingerprint: "abc" }),
false
);
});
test("isConfirmedAccount accepts a fully-formed entry", () => {
assert.equal(
isConfirmedAccount({ service: "zed-openai", account: "default", fingerprint: "abc123" }),
true
);
});
test("parseConfirmedAccounts returns null for missing / malformed bodies", () => {
assert.equal(parseConfirmedAccounts(null), null);
assert.equal(parseConfirmedAccounts({}), null);
assert.equal(parseConfirmedAccounts({ confirmedAccounts: "not-an-array" }), null);
assert.equal(
parseConfirmedAccounts({ confirmedAccounts: [{ service: 1 }] }),
null,
"an array with a malformed entry should fail validation"
);
});
test("parseConfirmedAccounts returns the list when every entry is valid", () => {
const result = parseConfirmedAccounts({
confirmedAccounts: [
{ service: "zed-openai", account: "default", fingerprint: "abc123" },
{ service: "zed-anthropic", account: "default", fingerprint: "def456" },
],
});
assert.ok(result);
assert.equal(result!.length, 2);
});
test("filterCredentialsByConfirmation only returns credentials matching the fingerprint set", () => {
const credentials = [
{ provider: "openai", service: "zed-openai", account: "default", token: "sk-real-1" },
{ provider: "anthropic", service: "zed-anthropic", account: "default", token: "sk-real-2" },
{ provider: "google", service: "zed-google", account: "default", token: "sk-real-3" },
];
// Operator confirmed only openai and anthropic; the matching fingerprints
// come from the same algorithm used by /discover.
const confirmed = [
{
service: "zed-openai",
account: "default",
fingerprint: fingerprintZedCredential("zed-openai", "default", "sk-real-1"),
},
{
service: "zed-anthropic",
account: "default",
fingerprint: fingerprintZedCredential("zed-anthropic", "default", "sk-real-2"),
},
];
const result = filterCredentialsByConfirmation(credentials, confirmed);
assert.equal(result.length, 2);
assert.deepEqual(
result.map((c) => c.provider).sort(),
["anthropic", "openai"]
);
});
test("filterCredentialsByConfirmation rejects entries with mismatched fingerprint (token rotation)", () => {
const credentials = [
{ provider: "openai", service: "zed-openai", account: "default", token: "sk-NEW-rotated" },
];
// Operator's confirmation references the OLD token's fingerprint.
const confirmed = [
{
service: "zed-openai",
account: "default",
fingerprint: fingerprintZedCredential("zed-openai", "default", "sk-old-token"),
},
];
const result = filterCredentialsByConfirmation(credentials, confirmed);
assert.equal(
result.length,
0,
"fingerprint mismatch (token rotated since discover) must skip the credential"
);
});