Update CSP to allow external fonts, scripts, and add corresponding test coverage
This commit is contained in:
+1
-1
@@ -439,7 +439,7 @@
|
||||
integrity="sha512-rCQgmUulW6f6QegOvTntKKb5IAoxTpGVCdWqYjkXEpzAns6XUFs8NKVqWe+KQpctp/EoRSFSuykVputqknLYMg=="
|
||||
crossorigin="anonymous" defer></script>
|
||||
<script src="/vendor/dompurify.js" defer></script>
|
||||
<script type="module" src="/js/script.js?v=20260930-chat-usability"></script>
|
||||
<script type="module" src="/js/script.js?v=20261007-chat-csp-fix"></script>
|
||||
<script type="module" src="/js/workspaceNavigation.js?v=20260909-account-controls"></script>
|
||||
</body>
|
||||
|
||||
|
||||
+1
-1
@@ -1017,7 +1017,7 @@ if (headerModelButton) headerModelButton.addEventListener("click", (event) => {
|
||||
});
|
||||
saveGenerationSettingsBtn.addEventListener("click", () => { void saveGenerationSettings(); });
|
||||
roleplayNewPersonaBtn.addEventListener("click", closeRoleplayStarter);
|
||||
clearUserPersonaBtn.addEventListener("click", () => {
|
||||
if (clearUserPersonaBtn) clearUserPersonaBtn.addEventListener("click", () => {
|
||||
closeChatDrawer();
|
||||
void clearChatUserPersona();
|
||||
});
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ function sameOriginProtection(config) {
|
||||
|
||||
function browserSecurityHeaders(config) {
|
||||
return (_req, res, next) => {
|
||||
res.setHeader("Content-Security-Policy", "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob:; media-src 'self' blob:; connect-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self' data:; worker-src 'self' blob:");
|
||||
res.setHeader("Content-Security-Policy", "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob:; media-src 'self' blob:; connect-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; font-src 'self' data: https://fonts.gstatic.com; worker-src 'self' blob:");
|
||||
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
|
||||
res.setHeader("Permissions-Policy", "camera=(), microphone=(), geolocation=(), payment=(), usb=()");
|
||||
res.setHeader("X-Content-Type-Options", "nosniff");
|
||||
|
||||
@@ -127,6 +127,16 @@ test("public health checks reach the backend without exposing diagnostics or req
|
||||
assert.equal((await request(server.baseUrl, "/admin/diagnostics")).status, 403);
|
||||
});
|
||||
|
||||
test("CSP permits the pinned chat markdown script and the app's hosted fonts", async t => {
|
||||
const server = await startTestServer();
|
||||
t.after(() => server.close());
|
||||
const response = await fetch(`${server.baseUrl}/`);
|
||||
const policy = response.headers.get("content-security-policy");
|
||||
assert.match(policy, /style-src[^;]*https:\/\/fonts\.googleapis\.com/);
|
||||
assert.match(policy, /script-src[^;]*https:\/\/cdnjs\.cloudflare\.com/);
|
||||
assert.match(policy, /font-src[^;]*https:\/\/fonts\.gstatic\.com/);
|
||||
});
|
||||
|
||||
test("personality API keeps prompts private, validates IDs, and enforces chat ownership", async t => {
|
||||
const server = await startTestServer();
|
||||
t.after(() => server.close());
|
||||
|
||||
Reference in New Issue
Block a user