You know with this CSP configuration:
Content-Security-Policy: script-src 'self'
Then this code can’t be executed:
// Content-Security-Policy: script-src 'self'
const dangerousStringToBeEvaluated= "console.log('HACKED!')"
eval(dangerousStringToBeEvaluated) // EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'
But if I know some JavaScript file is cached in CacheStorage
(and is served by service-worker), then I can work around this limitation:
// Content-Security-Policy: script-src 'self'
const dangerousStringToBeEvaluated = "console.log('HACKED!')"
const cache = await caches.open('some-cache')
await cache.put(
'/some-file.js',
new Response(dangerousStringToBeEvaluated, {headers: {'Content-Type': 'application/javascript'}}),
)
And afterward, you see HACKED!
in your console, when /some-file.js
imported!
Is there any other CSP rule to prevent this behavior? For example, by limiting write-access to CacheStorage
?