diff options
| author | MohamedBassem <me@mbassem.com> | 2025-08-23 16:03:06 +0300 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2025-08-23 16:03:06 +0300 |
| commit | a4b2fc7ca89c7916a32a3e279ab3880ebaa7a734 (patch) | |
| tree | 0697484b3881a9a43d72a9e38ba58c24b081bfea /packages | |
| parent | 096af7efffe11be563844a361fafd6d158dd5c81 (diff) | |
| download | karakeep-a4b2fc7ca89c7916a32a3e279ab3880ebaa7a734.tar.zst | |
fix(security): Add CSP policies on asset serving path
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/api/utils/assets.ts | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/packages/api/utils/assets.ts b/packages/api/utils/assets.ts index 205e1a76..3da32ff2 100644 --- a/packages/api/utils/assets.ts +++ b/packages/api/utils/assets.ts @@ -22,6 +22,25 @@ export async function serveAsset(c: Context, assetId: string, userId: string) { }), ]); + // Default Headers + c.header("Content-type", metadata.contentType); + c.header("X-Content-Type-Options", "nosniff"); + c.header( + "Content-Security-Policy", + [ + "sandbox", + "default-src 'none'", + "base-uri 'none'", + "form-action 'none'", + "img-src https: data: blob:", + "style-src 'unsafe-inline' https:", + "connect-src 'none'", + "media-src https: data: blob:", + "object-src 'none'", + "frame-src 'none'", + ].join("; "), + ); + const range = c.req.header("Range"); if (range) { const parts = range.replace(/bytes=/, "").split("-"); @@ -38,7 +57,6 @@ export async function serveAsset(c: Context, assetId: string, userId: string) { c.header("Content-Range", `bytes ${start}-${end}/${size}`); c.header("Accept-Ranges", "bytes"); c.header("Content-Length", (end - start + 1).toString()); - c.header("Content-type", metadata.contentType); return stream(c, async (stream) => { await stream.pipe(toWebReadableStream(fStream)); }); @@ -49,7 +67,6 @@ export async function serveAsset(c: Context, assetId: string, userId: string) { }); c.status(200); c.header("Content-Length", size.toString()); - c.header("Content-type", metadata.contentType); return stream(c, async (stream) => { await stream.pipe(toWebReadableStream(fStream)); }); |
