mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
🤖 fix: add security headers
- add Nitro middleware to set CSP + security headers for HTML responses - normalize raw file CSP string literal for Biome Tests: bun run lint:biome; bun run lint:oxlint
This commit is contained in:
@@ -337,7 +337,7 @@ describe('httpApiV1 handlers', () => {
|
||||
expect(await response.text()).toBe('hello')
|
||||
expect(response.headers.get('Content-Type')).toBe('text/plain; charset=utf-8')
|
||||
expect(response.headers.get('X-Content-Type-Options')).toBe('nosniff')
|
||||
expect(response.headers.get('Content-Security-Policy')).toBe('sandbox; default-src \'none\'')
|
||||
expect(response.headers.get('Content-Security-Policy')).toBe("sandbox; default-src 'none'")
|
||||
expect(response.headers.get('X-Content-SHA256')).toBe('abcd')
|
||||
})
|
||||
|
||||
@@ -383,7 +383,7 @@ describe('httpApiV1 handlers', () => {
|
||||
expect(await response.text()).toBe('hello')
|
||||
expect(response.headers.get('Content-Type')).toBe('text/plain; charset=utf-8')
|
||||
expect(response.headers.get('X-Content-Type-Options')).toBe('nosniff')
|
||||
expect(response.headers.get('Content-Security-Policy')).toBe('sandbox; default-src \'none\'')
|
||||
expect(response.headers.get('Content-Security-Policy')).toBe("sandbox; default-src 'none'")
|
||||
expect(response.headers.get('X-Content-SHA256')).toBe('abcd')
|
||||
})
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ const RATE_LIMITS = {
|
||||
} as const
|
||||
const MAX_RAW_FILE_BYTES = 200 * 1024
|
||||
const RAW_FILE_CONTENT_TYPE = 'text/plain; charset=utf-8'
|
||||
const RAW_FILE_CSP = 'sandbox; default-src \'none\''
|
||||
const RAW_FILE_CSP = "sandbox; default-src 'none'"
|
||||
|
||||
type SearchSkillEntry = {
|
||||
score: number
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { defineEventHandler, getRequestHeader, setHeader } from 'h3'
|
||||
|
||||
const CSP = [
|
||||
"default-src 'self'",
|
||||
"base-uri 'self'",
|
||||
"form-action 'self'",
|
||||
"frame-ancestors 'none'",
|
||||
"object-src 'none'",
|
||||
"script-src 'self' 'unsafe-inline'",
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data: https: blob:",
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self' https: wss:",
|
||||
].join('; ')
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const accept = getRequestHeader(event, 'accept') ?? ''
|
||||
const isHtml = accept.includes('text/html')
|
||||
|
||||
if (isHtml && process.env.NODE_ENV === 'production') {
|
||||
setHeader(event, 'Content-Security-Policy', CSP)
|
||||
}
|
||||
|
||||
setHeader(event, 'Permissions-Policy', 'camera=(), microphone=(), geolocation=(), payment=()')
|
||||
setHeader(event, 'Referrer-Policy', 'strict-origin-when-cross-origin')
|
||||
setHeader(event, 'X-Content-Type-Options', 'nosniff')
|
||||
setHeader(event, 'X-Frame-Options', 'DENY')
|
||||
})
|
||||
Reference in New Issue
Block a user