From b638509e34c9e32ac6fd30b36fee48db9129d243 Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 13 Aug 2021 16:21:52 -0400 Subject: [PATCH] Add CSP to Image Optimization API --- packages/next/server/image-optimizer.ts | 2 ++ .../image-component/default/pages/xss-svg.js | 14 ++++++++++++ .../image-component/default/public/xss.svg | 9 ++++++++ .../default/test/index.test.js | 22 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 test/integration/image-component/default/pages/xss-svg.js create mode 100644 test/integration/image-component/default/public/xss.svg 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/image-component/default/pages/xss-svg.js b/test/integration/image-component/default/pages/xss-svg.js new file mode 100644 index 000000000000000..0a450471d7e7edd --- /dev/null +++ b/test/integration/image-component/default/pages/xss-svg.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/image-component/default/public/xss.svg b/test/integration/image-component/default/public/xss.svg new file mode 100644 index 000000000000000..4d8343adb145604 --- /dev/null +++ b/test/integration/image-component/default/public/xss.svg @@ -0,0 +1,9 @@ + + + XSS + + +

safe

+ + + \ No newline at end of file diff --git a/test/integration/image-component/default/test/index.test.js b/test/integration/image-component/default/test/index.test.js index f2fbccb4132802d..2754c1957f45825 100644 --- a/test/integration/image-component/default/test/index.test.js +++ b/test/integration/image-component/default/test/index.test.js @@ -229,6 +229,28 @@ function runTests(mode) { } }) + it('should not execute scripts inside svg image', async () => { + let browser + try { + browser = await webdriver(appPort, '/xss-svg') + 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( + appPort, + '/_next/image?url=%2Fxss.svg&w=256&q=75' + ) + expect(await browser.elementById('msg').text()).toBe('safe') + } finally { + if (browser) { + await browser.close() + } + } + }) + it('should work when using flexbox', async () => { let browser try {