From 817835fd6ae9d17a142e7710f9e5d1ecc7820eb8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 1 Jun 2026 20:13:45 +0200 Subject: [PATCH] fix(document): add rel=noopener noreferrer to viewer download link (CWE-1022) The error-state download link opened with target="_blank" but no rel, exposing the opener to reverse tabnavbabbing. Add rel="noopener noreferrer". Same-origin so low severity, but a one-token fix in a file this issue already touches. Refs #708 Co-Authored-By: Claude Opus 4.8 --- frontend/src/lib/document/DocumentViewer.svelte | 1 + .../src/lib/document/DocumentViewer.svelte.test.ts | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/frontend/src/lib/document/DocumentViewer.svelte b/frontend/src/lib/document/DocumentViewer.svelte index b0ce8af6..aa8a575f 100644 --- a/frontend/src/lib/document/DocumentViewer.svelte +++ b/frontend/src/lib/document/DocumentViewer.svelte @@ -72,6 +72,7 @@ let { {m.doc_download_link()} diff --git a/frontend/src/lib/document/DocumentViewer.svelte.test.ts b/frontend/src/lib/document/DocumentViewer.svelte.test.ts index a3982a0e..f5d70503 100644 --- a/frontend/src/lib/document/DocumentViewer.svelte.test.ts +++ b/frontend/src/lib/document/DocumentViewer.svelte.test.ts @@ -46,6 +46,20 @@ describe('DocumentViewer', () => { .toHaveAttribute('href', '/api/documents/d1/file'); }); + it('hardens the target=_blank download link with rel=noopener noreferrer (CWE-1022)', async () => { + render(DocumentViewer, { + props: { + ...baseProps, + doc: { ...baseProps.doc, filePath: 'docs/scan.pdf' }, + error: 'Render failed' + } + }); + + await expect + .element(page.getByRole('link', { name: /direkter download/i })) + .toHaveAttribute('rel', 'noopener noreferrer'); + }); + it('omits the direct-download link in the error state when filePath is null', async () => { render(DocumentViewer, { props: { ...baseProps, error: 'Render failed' } });