0
0
mirror of https://github.com/honojs/hono.git synced 2024-12-01 03:40:50 +01:00

fix(secure-headers): optimize getPermissionsPolicyDirectives function (#3398)

This commit is contained in:
kbkn3 2024-09-09 21:54:27 +09:00 committed by GitHub
parent c2b0de42a0
commit 3c4d4c2b59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 5 deletions

View File

@ -160,7 +160,7 @@ describe('Secure Headers Middleware', () => {
expect(res.headers.get('X-XSS-Protection')).toEqual('1') expect(res.headers.get('X-XSS-Protection')).toEqual('1')
}) })
it('should set Permission-Policy header', async () => { it('should set Permission-Policy header correctly', async () => {
const app = new Hono() const app = new Hono()
app.use( app.use(
'/test', '/test',
@ -173,13 +173,20 @@ describe('Secure Headers Middleware', () => {
camera: false, camera: false,
microphone: true, microphone: true,
geolocation: ['*'], geolocation: ['*'],
usb: ['self', 'https://a.example.com', 'https://b.example.com'],
accelerometer: ['https://*.example.com'],
gyroscope: ['src'],
magnetometer: ['https://a.example.com', 'https://b.example.com'],
}, },
}) })
) )
const res = await app.request('/test') const res = await app.request('/test')
expect(res.headers.get('Permissions-Policy')).toEqual( expect(res.headers.get('Permissions-Policy')).toEqual(
'fullscreen=(self), bluetooth=(none), payment=(self example.com), sync-xhr=(), camera=none, microphone=(), geolocation=(*)' 'fullscreen=(self), bluetooth=none, payment=(self "example.com"), sync-xhr=(), camera=none, microphone=*, ' +
'geolocation=*, usb=(self "https://a.example.com" "https://b.example.com"), ' +
'accelerometer=("https://*.example.com"), gyroscope=(src), ' +
'magnetometer=("https://a.example.com" "https://b.example.com")'
) )
}) })
it('CSP Setting', async () => { it('CSP Setting', async () => {

View File

@ -278,12 +278,18 @@ function getPermissionsPolicyDirectives(policy: PermissionsPolicyOptions): strin
const kebabDirective = camelToKebab(directive) const kebabDirective = camelToKebab(directive)
if (typeof value === 'boolean') { if (typeof value === 'boolean') {
return `${kebabDirective}=${value ? '()' : 'none'}` return `${kebabDirective}=${value ? '*' : 'none'}`
} }
if (Array.isArray(value)) { if (Array.isArray(value)) {
const allowlist = value.length === 0 ? '()' : `(${value.join(' ')})` if (value.length === 0) {
return `${kebabDirective}=${allowlist}` return `${kebabDirective}=()`
}
if (value.length === 1 && (value[0] === '*' || value[0] === 'none')) {
return `${kebabDirective}=${value[0]}`
}
const allowlist = value.map((item) => (['self', 'src'].includes(item) ? item : `"${item}"`))
return `${kebabDirective}=(${allowlist.join(' ')})`
} }
return '' return ''