import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { test } from 'node:test'; const config = readFileSync(process.env.CAPTCHA_NGINX_CONFIG ?? new URL('../deploy/web.nginx.conf', import.meta.url), 'utf8'); const headers = [...config.matchAll(/add_header\s+Content-Security-Policy\s+"([^"]+)"\s+always/g)]; assert.ok(headers.length, 'HTML must retain an enforced Content-Security-Policy'); const policies = headers.map(([, header]) => new Map(header.split(';').map(value => value.trim().split(/\s+/)).filter(([name]) => name).map(([name, ...sources]) => [name, sources]))); test('Tencent CAPTCHA entry, secondary scripts and styles are allowed', () => { for (const policy of policies) { for (const host of ['https://turing.captcha.qcloud.com', 'https://turing.captcha.gtimg.com']) { assert.ok(policy.get('script-src')?.includes(host), `${host} must be allowed for scripts`); assert.ok(policy.get('style-src')?.includes(host), `${host} must be allowed for styles`); } } }); test('CAPTCHA blob workers are permitted without allowing blob scripts', () => { for (const policy of policies) { assert.deepEqual(policy.get('worker-src'), ["'self'", 'blob:']); assert.ok(!policy.get('script-src')?.includes('blob:')); } }); test('strict script and document protections remain in force', () => { const allowedScripts = new Set(["'self'", 'https://turing.captcha.gtimg.com', 'https://turing.captcha.qcloud.com', 'https://ssl.captcha.qq.com']); for (const policy of policies) { assert.ok(policy.get('script-src')?.every(source => allowedScripts.has(source)), 'no inline/eval or broad script wildcards'); assert.deepEqual(policy.get('default-src'), ["'self'"]); assert.deepEqual(policy.get('frame-ancestors'), ["'none'"]); assert.deepEqual(policy.get('base-uri'), ["'self'"]); } });