VYPR
High severityNVD Advisory· Published Aug 30, 2021· Updated Aug 4, 2024

XSS in Image Optimization API for Next.js versions between 10.0.0 and 11.1.0

CVE-2021-39178

Description

Next.js is a React framework. Versions of Next.js between 10.0.0 and 11.0.0 contain a cross-site scripting vulnerability. In order for an instance to be affected by the vulnerability, the next.config.js file must have images.domains array assigned and the image host assigned in images.domains must allow user-provided SVG. If the next.config.js file has images.loader assigned to something other than default or the instance is deployed on Vercel, the instance is not affected by the vulnerability. The vulnerability is patched in Next.js version 11.1.1.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
nextnpm
>= 10.0.0, < 11.1.111.1.1

Affected products

1

Patches

1
7afc97c5744b

Add CSP to Image Optimization API (#28620)

https://github.com/vercel/next.jsStevenAug 30, 2021via ghsa
5 files changed · +45 1
  • packages/next/server/image-optimizer.ts+2 0 modified
    @@ -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 }
     }
     
    
  • test/integration/production/pages/svg-image.js+14 0 added
    @@ -0,0 +1,14 @@
    +import React from 'react'
    +import Image from 'next/image'
    +
    +const Page = () => {
    +  return (
    +    <div>
    +      <h1>SVG with a script tag attempting XSS</h1>
    +      <Image id="img" src="/xss.svg" width="100" height="100" />
    +      <p id="msg">safe</p>
    +    </div>
    +  )
    +}
    +
    +export default Page
    
  • test/integration/production/public/xss.svg+9 0 added
    @@ -0,0 +1,9 @@
    +<html xmlns="http://www.w3.org/1999/xhtml">
    +<head>
    +  <title>XSS</title>
    +</head>
    +<body>
    +  <p id="msg">safe</p>
    +  <script>document.getElementById('msg').textContent='hacked'</script>
    +</body>
    +</html>
    
  • test/integration/production/test/index.test.js+1 1 modified
    @@ -78,7 +78,7 @@ describe('Production Usage', () => {
       })
     
       it('should contain generated page count in output', async () => {
    -    const pageCount = process.env.NEXT_PRIVATE_TEST_WEBPACK4_MODE ? 37 : 38
    +    const pageCount = process.env.NEXT_PRIVATE_TEST_WEBPACK4_MODE ? 38 : 39
         expect(output).toContain(`Generating static pages (0/${pageCount})`)
         expect(output).toContain(
           `Generating static pages (${pageCount}/${pageCount})`
    
  • test/integration/production/test/security.js+19 0 modified
    @@ -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()
    +      }
    +    })
       })
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.