diff --git a/docs/content/1.docs/2.features/blob.md b/docs/content/1.docs/2.features/blob.md index 81e7cfe0..17ca2932 100644 --- a/docs/content/1.docs/2.features/blob.md +++ b/docs/content/1.docs/2.features/blob.md @@ -73,8 +73,7 @@ Returns [`BlobListResult`](#bloblistresult). ### `serve()` -Returns a blob's data. - +Returns a blob's data and sets `Content-Type`, `Content-Length` and `ETag` headers. ::code-group ```ts [server/routes/images/[...pathname\\].get.ts] @@ -91,6 +90,21 @@ export default eventHandler(async (event) => { ``` :: +::important +To prevent XSS attacks, make sure to control the Content type of the blob you serve. +:: + +You can also set a `Content-Security-Policy` header to add an additional layer of security: + +```ts [server/api/images/[...pathname\\].get.ts] +export default eventHandler(async (event) => { + const { pathname } = getRouterParams(event) + + setHeader(event, 'Content-Security-Policy', 'default-src \'none\';') + return hubBlob().serve(event, pathname) +}) +``` + #### Params ::field-group diff --git a/playground/server/api/blob/[...pathname].get.ts b/playground/server/api/blob/[...pathname].get.ts index 4685cbfe..bec81713 100644 --- a/playground/server/api/blob/[...pathname].get.ts +++ b/playground/server/api/blob/[...pathname].get.ts @@ -2,6 +2,6 @@ export default eventHandler(async (event) => { const { pathname } = await getValidatedRouterParams(event, z.object({ pathname: z.string().min(1) }).parse) - + setHeader(event, 'Content-Security-Policy', 'default-src \'none\';') return hubBlob().serve(event, pathname) })