mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-06 17:04:57 +00:00
fix(desktop): protect packaged renderer scripts
This commit is contained in:
parent
ec0dcb3da9
commit
c7ca52286a
3 changed files with 39 additions and 11 deletions
16
packages/desktop/src/main/windows/document-headers.test.ts
Normal file
16
packages/desktop/src/main/windows/document-headers.test.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { addDocumentHeaders } from "./document-headers"
|
||||
|
||||
test("protects packaged renderer documents", () => {
|
||||
const response = addDocumentHeaders(new Response("app"), "/renderer/index.html")
|
||||
|
||||
expect(response.headers.get("content-security-policy")).toContain("script-src 'self' 'wasm-unsafe-eval'")
|
||||
expect(response.headers.get("content-security-policy")).toContain("object-src 'none'")
|
||||
expect(response.headers.get("content-security-policy")).toContain("base-uri 'none'")
|
||||
expect(response.headers.get("document-policy")).toBe("include-js-call-stacks-in-crash-reports")
|
||||
})
|
||||
|
||||
test("leaves renderer assets unchanged", () => {
|
||||
const response = new Response("script")
|
||||
expect(addDocumentHeaders(response, "/renderer/app.js")).toBe(response)
|
||||
})
|
||||
20
packages/desktop/src/main/windows/document-headers.ts
Normal file
20
packages/desktop/src/main/windows/document-headers.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const contentSecurityPolicy = [
|
||||
"default-src 'self'",
|
||||
"script-src 'self' 'wasm-unsafe-eval'",
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data: https: blob:",
|
||||
"font-src 'self' data:",
|
||||
"media-src 'self' data:",
|
||||
"connect-src * data: blob:",
|
||||
"worker-src 'self' blob:",
|
||||
"object-src 'none'",
|
||||
"base-uri 'none'",
|
||||
].join("; ")
|
||||
|
||||
export function addDocumentHeaders(response: Response, file: string) {
|
||||
if (!file.toLowerCase().endsWith(".html")) return response
|
||||
const headers = new Headers(response.headers)
|
||||
headers.set("Content-Security-Policy", contentSecurityPolicy)
|
||||
headers.set("Document-Policy", "include-js-call-stacks-in-crash-reports")
|
||||
return new Response(response.body, { status: response.status, statusText: response.statusText, headers })
|
||||
}
|
||||
|
|
@ -4,11 +4,10 @@ import { pathToFileURL } from "node:url"
|
|||
import { Effect, Path } from "effect"
|
||||
import { scoped } from "../native/logging"
|
||||
import { DesktopPaths } from "../paths"
|
||||
import { addDocumentHeaders } from "./document-headers"
|
||||
|
||||
const rendererProtocol = "oc"
|
||||
const rendererHost = "renderer"
|
||||
const documentPolicyHeader = "Document-Policy"
|
||||
const jsCallStacksDocumentPolicy = "include-js-call-stacks-in-crash-reports"
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{
|
||||
|
|
@ -58,7 +57,7 @@ export const registerRendererProtocol = Effect.fn("Window.registerRendererProtoc
|
|||
),
|
||||
)
|
||||
}
|
||||
return addDocumentPolicy(response, file)
|
||||
return addDocumentHeaders(response, file)
|
||||
} catch (error) {
|
||||
runFork(scoped("protocol", Effect.logError("fetch error", { url: request.url, file, error })))
|
||||
return new Response("Not found", { status: 404 })
|
||||
|
|
@ -88,17 +87,10 @@ export function isRendererUrl(value?: string, html = false) {
|
|||
export function addRendererHeaders(value: string, headers: object) {
|
||||
upsertHeader(headers, "Access-Control-Allow-Origin", ["*"])
|
||||
upsertHeader(headers, "Access-Control-Allow-Headers", ["*"])
|
||||
if (isRendererUrl(value, true)) upsertHeader(headers, documentPolicyHeader, [jsCallStacksDocumentPolicy])
|
||||
if (isRendererUrl(value, true)) upsertHeader(headers, "Document-Policy", ["include-js-call-stacks-in-crash-reports"])
|
||||
}
|
||||
|
||||
export function upsertHeader(headers: object, key: string, value: string | string[]) {
|
||||
const current = Object.keys(headers).find((header) => header.toLowerCase() === key.toLowerCase())
|
||||
Reflect.set(headers, current ?? key, value)
|
||||
}
|
||||
|
||||
function addDocumentPolicy(response: Response, file: string) {
|
||||
if (!file.toLowerCase().endsWith(".html")) return response
|
||||
const headers = new Headers(response.headers)
|
||||
headers.set(documentPolicyHeader, jsCallStacksDocumentPolicy)
|
||||
return new Response(response.body, { status: response.status, statusText: response.statusText, headers })
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue