diff --git a/packages/next/server/image-optimizer.ts b/packages/next/server/image-optimizer.ts index eabb4ee55a35cdd..a2d7c6a664d0c98 100644 --- a/packages/next/server/image-optimizer.ts +++ b/packages/next/server/image-optimizer.ts @@ -525,6 +525,8 @@ function setResponseHeaders( res.setHeader('Content-Disposition', `inline; filename="${fileName}"`) } + res.setHeader('Content-Security-Policy', `script-src 'none'; sandbox;`) + return { finished: false } } diff --git a/test/integration/production/pages/svg-image.js b/test/integration/production/pages/svg-image.js new file mode 100644 index 000000000000000..0a450471d7e7edd --- /dev/null +++ b/test/integration/production/pages/svg-image.js @@ -0,0 +1,14 @@ +import React from 'react' +import Image from 'next/image' + +const Page = () => { + return ( +
+

SVG with a script tag attempting XSS

+ +

safe

+
+ ) +} + +export default Page diff --git a/test/integration/production/public/xss.svg b/test/integration/production/public/xss.svg new file mode 100644 index 000000000000000..c3e80bb95a209fe --- /dev/null +++ b/test/integration/production/public/xss.svg @@ -0,0 +1,9 @@ + + + XSS + + +

safe

+ + + diff --git a/test/integration/production/test/security.js b/test/integration/production/test/security.js index afc501e88d950b7..76b15b72c2ca08c 100644 --- a/test/integration/production/test/security.js +++ b/test/integration/production/test/security.js @@ -342,5 +342,24 @@ module.exports = (context) => { expect(pathname).toBe('/%2fexample.com') expect(hostname).not.toBe('example.com') }) + + it('should not execute script embedded inside svg image', async () => { + let browser + try { + browser = await webdriver(context.appPort, '/svg-image') + await browser.eval(`document.getElementById("img").scrollIntoView()`) + expect(await browser.elementById('img').getAttribute('src')).toContain( + 'xss.svg' + ) + expect(await browser.elementById('msg').text()).toBe('safe') + browser = await webdriver( + context.appPort, + '/_next/image?url=%2Fxss.svg&w=256&q=75' + ) + expect(await browser.elementById('msg').text()).toBe('safe') + } finally { + if (browser) await browser.close() + } + }) }) }