diff --git a/packages/opencode/src/plugin/codex.ts b/packages/opencode/src/plugin/codex.ts index bdeef9823f..84fec79b99 100644 --- a/packages/opencode/src/plugin/codex.ts +++ b/packages/opencode/src/plugin/codex.ts @@ -10,6 +10,10 @@ import { createServer } from "http" const log = Log.create({ service: "plugin.codex" }) +function escapeHtml(str: string): string { + return str.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'") +} + const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann" const ISSUER = "https://auth.openai.com" const CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses" @@ -230,7 +234,7 @@ const HTML_ERROR = (error: string) => `

Authorization Failed

An error occurred during authorization.

-
${error}
+
${escapeHtml(error)}
` diff --git a/packages/opencode/test/plugin/codex-xss.test.ts b/packages/opencode/test/plugin/codex-xss.test.ts new file mode 100644 index 0000000000..146d2b083b --- /dev/null +++ b/packages/opencode/test/plugin/codex-xss.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, test } from "bun:test" + +/** + * CWE-79: XSS in codex.ts HTML_ERROR + * File: packages/opencode/src/plugin/codex.ts + * + * HTML_ERROR interpolated error string directly into HTML. + * Fix: escapeHtml() sanitizes the error before interpolation. + */ + +function escapeHtml(str: string): string { + return str.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'") +} + +const HTML_ERROR = (error: string) => `
${escapeHtml(error)}
` + +describe("CWE-79: XSS in codex.ts HTML_ERROR", () => { + test("should escape script tags", () => { + const result = HTML_ERROR('') + expect(result).not.toContain("