A security team from one of our partners noticed an issue in Next.js that allowed for an open redirect to occur.
Specially encoded paths could be used when pages/_error.js
was statically generated allowing an open redirect to occur to an external site.
In general, this redirect does not directly harm users although can allow for phishing attacks by redirecting to an attacker's domain from a trusted domain.
We recommend upgrading to the latest version of Next.js to improve the overall security of your application.
How to Upgrade
- We have released patch versions for both the stable and canary channels of Next.js.
- To upgrade run
npm install next@latest --save
Impact
- Affected: Users of Next.js between 10.0.5 and 10.2.0
- Affected: Users of Next.js between 11.0.0 and 11.0.1 using
pages/_error.js
withoutgetInitialProps
- Affected: Users of Next.js between 11.0.0 and 11.0.1 using
pages/_error.js
andnext export
- Not affected: Deployments on Vercel (vercel.com) are not affected
- Not affected: Deployments with
pages/404.js
We recommend everyone to upgrade regardless of whether you can reproduce the issue or not.
How to Assess Impact
If you think sensitive code or data could have been exposed, you can filter logs of affected sites by //
(double slash at the start of the url) followed by a domain.
What is Being Done
As Next.js has grown in popularity and usage by enterprises, it has received the attention of security researchers and auditors. We are thankful to Gabriel Benmergui from Robinhood for their investigation and discovery of the original bug and subsequent responsible disclosure.
We've landed a patch that ensures path parsing is handled properly for these paths so that the open redirect can no longer occur.
Regression tests for this attack were added to the security integration test suite
- We have notified known Next.js users in advance of this publication.
- A public CVE was released.
- We encourage responsible disclosure of future reports. Please email us at
security@vercel.com
. We are actively monitoring this mailbox.
Release notes
Core Changes
- Don't test image domains in test env: #26502
- Fix props not updating when changing the locale and keeping hash: #26205
- Allow user to override next-image-loader: #26548
- Add logging when a custom babelrc is loaded: #26570
- Add comment to not edit in next-env file: #26573
- Add trace url on bootup: #26594
- Add check for ObjectExpression when iterating on tags for font optimization: #26608
- Fix GSP redirect cache error: #26627
- Correct statusCode when visiting _error directly: #26610
- fix: next dynamic with jest: #26614
- Ensure API routes are not available under the locale: #26629
- Fix image content type octet stream 400: #26705
- [ESLint] Adds --max-warnings flag to
next lint
: #26697 - Simplify
next-dev-server
implementation: #26230 - Move code shared between server/client to "shared" folder: #26734
- Move next-server directory files to server directory: #26756
- Support new hydrate API in latest react 18 alpha release: #26664
- Add upstream
max-age
to optimized image: #26739 - Fix blurred image position when using objectPosition: #26590
- Leverage blocked page for _error: #26748
- fix: detect loop in client error page: #26567
- Add
onLoadingComplete()
prop to Image component: #26824 - Add "Vary: Accept" header to /_next/image responses: #26788
- Add additional tests for image type detection: #26832
- Fix immutable header for image with static import & unoptimized: #26836
- Make sure 404 pages do not get cached by a CDN when using next start: #24983
- Don't emit duplicate image files: #26843
- Warn when response body is larger than 5mb: #26831
- Fix: added the key property to the pre next scripts: #26646
- Ensure API route errors are propagated in minimal mode: #26875
- 5MB -> 4MB body size limit: #26887
- [ESLint] Update default
.eslintrc
file created to have.json
format: #26884 - Refactor decode failures: #26899
- Add initial
ResponsePayload
support: #26938 - Fix typo in route-loader: #26942
- More explicit typing for
IncrementalCache
API: #26941 - Fix merge issue and use
respondWith
: #26961 - (next/image): Merge query string params in imgix loader: #26719
- Fix: (rewrites) incorrect parsing of destination query: #26619
- Fix forward slash encoding while interpolating: #26963
- update webpack to 5.43.0: #26979
- Rename
next/script
interface Props to ScriptProps: #26990 - Don't lazy-load already-loaded image in client-side transition: #26968
- Loosen
next/image
TS types forwidth
andheight
: #26991 - Add
dangerously-unoptimized
loader for next/image: #26847 - Fix hash change events not firing with i18n: #26994
- Loosen
next/image
TS types forsrc
: #26996 - Provide Next.js postcss version to cssnano-simple: #26952
- Rename next/image
dangerously-unoptimized
tocustom
and warn when applicable: #26998 - Add newline to the end of
next-env.d.ts
: #27028 - Add performance tracing for next-image-loader: #27043
- Include message body in redirect responses: #25257
- add support for esm externals: #27069
- Enhance
next dev
performance with placeholder=blur: #27061 - Add batching to zipkin reporter: #27082
- Bind sendBeacon to navigator: #26601
- Fall back to fallbackSend when send is false: #27113
- Upgrades
web-vitals
to v1.1.2.: #25272 - Prevent timeout when loading routes in development: #25749
- Workaround for Node.js 16+ on Apple Silicon M1: #27031
- Replace
withCoalescedInvoke
withResponseCache
: #26997 - Add some missing fields to the NextConfig type: #27126
- Update redirect regexes to not match _next: #27143
- Bump babel target to Node.js 12: #27147
- Use SWC to compile Next.js core server files: #27167
- Fix css minify incorrectly duplicating variables: #27150
- Fix gsp generation with file extension: #27144
- Add
minimumCacheTTL
config for Image Optimization: #27200 - Fix Script beforeInteractive on navigation: #26995
- improve static generation UX: #27171
- Add warning for large number of routes: #27214
- Add x-forward headers to external rewrites: #17557
- [ESLint] Remove error when file patterns are unmatched + ESLint setup changes: #27119
- Fix inline scripts being duplicated when used with
next/script
component: #27218 - Fix
minimumCacheTTL
so it doesn't affect browser caching: #27307 - Fix default server host value causing issues on Windows: #27306
- Fix
placeholder=blur
inside<noscript>
: #27311 - fix type NextWebVitalsMetric: #24780
- Add
RequestContext
: #27303 - Fix ISR page re-rendering after revalidate expiry (Fork of #24807): #27335
- Update NextConfig type to not require experimental or future fields: #25517
- Allow enabling worker threads on dev server: #23027
- Refactor i18n checks on request handling: #27328
- Add configuration for ISR Memory Cache Size (#21535): #27337
- Rename spr config to ISR: #27379
- Add
keepAlive
tonode-fetch
polyfill: #27376 - Fix external redirect with i18n domains: #27415
- Don't cache
null
responses: #27403 - Use Sharp if available for Image Optimization: #27346
- Fix typo in error message: #27438
- Add
lazyBoundary
prop to Image component: #27258 - Ensure generateBuildId is not required in config type: #27443
- Add eslint config options to
NextConfig
type: #27446 - Wait for getFilesForRoute promise to fulfill before timeout in dev mode: #27395
- Add config check for invalid duplicate locale domains: #27451
- Add warning when
next/image
component hasstyle
prop: #27441 - [ESLint] Adds
--format
flag tonext lint
: #27052 - ESLint: custom directories from next.config.js: #26401
- Updated the Error message describing the alternative and added styles…: #14652
- Clarify error message in isSerializableProps: #22856
- Update eslint doc comment: #27478
- fix: Make router ready in case of custom _app getInitialProps: #27473
- fix(critical CSS): use the assetPrefix in the critters config: #27506
- Add initial next swc package with first transform: #27355
- Add
RenderResult
: #27319 - Document i18n locale limit: #27542
- Fix: Added the content-disposition header: #27521
- Use SWC for Next.js core client files: #27196
- upgrade to webpack 5.47.0 and webpack-sources 3.1.1: #27538
- persistent cache need to be invalidated when source-maps are enabled: #27607
- Update report to leverage new variables: #27084
- Update Terser: #27600
- Ensure Next.js core development sourcemaps use correct input file: #27623
- Undo sourcemap change : #27690
- URI-encode url parameter in image optimizer: #27671
- More React 17 clean up: #26775
- Enforce source/destination limit for custom routes: #27703
- Add naturalWidth/naturalHeight to
onLoadingComplete()
callback: #27695 - update webpack-sources to 3.2.0 for bugfixes and performance: #27673
- Add
next.config.js
option to override defaultkeepAlive
: #27709 - Port next-ssg getStaticProps/getServerSideProps tree shaking Babel transform to rust: #27552
- Add handling for repeated slashes: #27738
- Add/amp attribute patcher: #27700
- Add missing
removeHeader()
function to image optimizer mock res: #27763 - Fix html validation for Image component sizer: #27767
- Update has query encoding when used in path: #27762
- [ESLint] Introduce a new setup process when
next lint
is run for the first time: #26584 - remove unecessary fs.stat calls from recursive-readdir: #27769
- Wrap last return statement in
else
to fix tree shaking: #27788 - Update client error to show link in console: #27789
- Upgrade styled-jsx: #27782
- update webpack to 5.49.0: #27813
- Add experimental SWC minify and SWC loader options: #27664
- Use @vercel/fetch for run-tests requests: #27815
- Add next dynamic swc transform: #27745
- Add Import trace for requested module when it fails to resolve: #27840
- disable cache compression as it slows down the build: #27887
- Remove extraneous fs.stat calls: #27779
- Upgrade styled-jsx to v4: #27890
- Replace
placeholder
withblurDataURL
in globalStaticImageData
type: #27916 - Fix
next/script
unhandled promise rejection: #27903 - update to webpack 5.50.0: #27929
- Remove duplicate type for StaticImageData: #27931
- Add data-nimg attribute to image component: #27899
- test(next): add tests for Node-like hashbang support: #27906
- Add experimental
concurrentFeatures
config: #27768 - Add warning during
next build
when sharp is missing: #27933 - Next swc publish flow: #27932
Documentation Changes
- docs: updated minimum Node.js version: #26528
- Update next-env note in docs: #26536
- Add note about adding additional types: #26545
- chore: Enable Alex documentation linting for error pages: #26526
- Update SWR example to include fetcher function.: #26520
- doc: prettify docs for next script: #26572
- Enable Alex documentation linting for docs: #26598
- Update next/image docs for relative parent with layout=fill.: #26615
- Update to environment-variable.md: #26863
- Add instructions on how to add nextjs.org/docs/messages urls: #26865
- Reorder docs manifest and rename to Script Optimization.: #26874
- Fix typo on "occured" to "occurred": #26876
- Update data-fetching.md: #27018
- Docs/Typo: Replace triple dot character with real dots: #27030
- Mention customization of next.config.js to import images: #27104
- [docs] Layouts & Going to Production: #27021
- Add jsdoc types to docs snippets: #27125
- Fix code block in Layouts docs.: #27130
- Update Going to Production docs to use quote.: #27131
- Revert "Update data-fetching.md": #27148
- Change pure functions to functions: #27192
- [ESLint Plugin] Adds
no-duplicate-head
rule: #27179 - Fix typo in env howto: #27227
- Add note about beforeFiles continuing: #27211
- Document full routes order in rewrites doc: #27247
- Use named functions in layouts docs: #27297
- Update next-image-unconfigured-host.md: #24953
- Add extra explanation to next/image about positioning: #27341
- docs: add note for Image responsive layout: #25915
- Update docs around ISR revalidation: #25571
- Indicate attaching debugger (vs launching): #27377
- [errors/no-cache] Prevent GitHub Actions cache from going stale: #27362
- Clarify automatic updates in deployment.: #27418
- Update
next/image
docs withonLoadingComplete()
: #27440 - Update max-age in HSTS sample: #27452
- [ESLint] add no-typos rule to eslint: #26650
- Fixed minor grammar issue: #27493
- Fix typo in placeholder-blur-data-url error docs: #27510
- Update custom-page-extensions.md: #27541
- Document redirect query passing behavior: #27545
- [docs] Added per page layout example with TypeScript: #27488
- Fix incorrect example in headers and rewrites docs: #27652
- Clarify in docs that
next/script
must not be innext/head
: #27534 - Improve custom server documentation.: #27693
- Add a note about the existence of 'next/script': #27725
- [ESLint] Documentation updates + bug fixes: #26331
- fix eslint plugin install instructions in docs: #27807
- Document that Google has begun using CLS metric: #27843
- Little typo: #27911
- Adding a missing a period: #27928
- Add manifest check step and add missing items: #27934
Example Changes
- [examples] Fix ssr-caching example.: #26540
- tailwind examps upgraded to v2.2: #26549
- fix with-loading example for next 11: #26569
- Add link to live demo already hosted: #25718
- Update layouts example to persist state across client-side transitions.: #26706
- Fix typo on "occured" to "occurred": #26709
- update with-redux-toolkit-typescript: #26714
- examples: fix typo
lunix
→linux
: #26796 - Fix using-preact example deps: #26821
- Use Prismic CDN URL in cms-prismic example: #26837
- Updated next-transpile-modules to 8.0.0: #26971
- Fix (trailingSlash: true) causes issue in auth0 example: #27010
- Update dependencies of all CMS examples.: #27001
- Update SuperTokens dependency version in with-supertokens example: #27110
- fix tailwind error: #27042
- [examples] Use Strapi template: #27114
- Clean up examples
package.json
: #27121 - Fix Image is missing required "src" property error: #27180
- Fix Prop
href
did not match error: #27183 - upgrade next-redux-wrapper to 7.0.2: #26521
- updated zustand example for 3.5.4+ interface change: #27229
- Update cms-wordpress readme file: #27234
- update fastify example to the latest version: #27273
- Remove redundant ssr option for styled-components: #27221
- Optimised Cypher queries in Neo4j example: #25973
- (examples/with-i18n-next-intl): fixes warning : #25928
- Continue: fix typo in breakpoint config: #27313
- Continue: Update blog-starter-typescript postcss.config.js: #27314
- Fix image link: #27323
- Update layout-component example to use named functions: #27331
- fix: hydration warning in with-mobx-state-tree-typescript example: #27339
- Update graphql example: #27334
- Examples: Delete
as
prop from<Link>
components: #27359 - Fixed typo and error when using Auth0 service;: #27383
- Rename
util
tolib
inwith-mongodb
example: #27404 - Rename
utils
tolib
inwith-mongodb-mongoose
example: #27407 - Add locale switcher to i18n-routing example: #27444
- Auth0 Example: Fix issuer base URL: #27074
- Fix CORS issue in GraphQL example that prevented Apollo Studio from working: #27486
- [typo] posts.map( posts => {} ) in examples/blog-starter-typescript: #27523
- Drop react-is dependency in styled-components example: #27527
- Revert "Drop react-is dependency in styled-components example (#27527)": #27543
- Added missing 'create user' functionality: #27516
- Add missing await for API request: #27676
- Update Fauna example with new guestbook: #27295
- Patch with-fauna example.: #27701
- Add with-joi example: #25759
- Fix create-strapi-app instruction in strapi example: #27707
- Rename environment variable in Fauna example.: #27712
- Update Fauna example to create Fauna resources properly: #27757
- fix wrong link in readme: #27802
- Update with-jest example: #27894
- Add with-cypress example: #27900
Misc Changes
- Separate node polyfill test from basic suite: #26550
- Update PR labeler action
- Simplify stats action: #26751
- Disable build-output size specific tests: #26769
- Update azure tests: #26779
- Stabilize relay-analytics test: #26782
- Update codeowners to add new maintainers: #26770
- Update repo scripts to separate folder: #26787
- Update snapshot for font-optimization test: #26823
- Update
publish-canary
script to include checkout: #26840 - include image types in
create-next-app
next-env.d.ts: #26890 - fix error message during create-next-app: #26980
- Add page with next/image to stats-app: #26973
- [ESLint] Removes image rule as error in Core Web Vitals config: #26967
- Update labeler.json
- Mention running local changes inside monorepo: #27050
- Add test for
placeholder=blur
withassetPrefix
: #27120 - Update the "Top level .mdx pages" code sample: #27080
- Add additional stats app pages: #27202
- Add NextPage type to create-next-app typescript template: #27246
- Increase stats action install timeout: #27308
- Upgrade swc for mac m1 compiling issue: #27329
- chore: Set Prettier to ignore integration output HTMLs: #26353
- Support multiple pages directories for linting: #25565
- Increase PR stats repo build timeout: #27419
- [eslint] move core-web-vitals config to eslint-plugin-next: #27363
- Add --dev flag to bundle-analyzer install command: #27463
- change ts template readme api/index file extension from tsx to ts: #27485
- Update bundle analyzer readme: #27507
- ESLint Config: Adds some more basic a11y rules: #25770
- Fix eslint config next/core-web-vitals: #27567
- Only output test logs on failure in CI: #27604
- Use require alias to resolve react 18 for testing: #27601
- move
next/script
topages/_app
in script loader integration tests: #27626 - Minor typo fix in the @next/mdx README: #27784
- Remove codeowners from examples: #27798
- Updates Aurora team members in labeler: #27795
- Add sourceFileName for SWC compiled core files
- feat(package.json): add contributor-friendly lifecycle scripts: #27825
- Add type annotation for NextConfig to CNA typescript template: #27872
- Update release stats job name: #27923
- Add rootDir setting to eslint-plugin-next: #27918
- Revert "Next swc publish flow (#27932)"
- Revert "Add warning during
next build
when sharp is missing (#27933)"
Credits
Huge thanks to @atcastle, @vitalybaev, @leerob, @destruc7i0n, @styfle, @petermekhaeil, @phocks, @pranavp10, @huozhi, @ijjk, @johnrackles, @timneutkens, @Vadorequest, @hiro0218, @housseindjirdeh, @sohamsshah, @devknoll, @schoenwaldnils, @kasipavankumar, @jviide, @sedlukha, @PaulvdDool, @padmaia, @LetItRock, @angeloashmore, @sachinraja, @pa-rang, @theostrahlen, @schultzp2020, @lsndr, @sokra, @andys-github, @darshkpatel, @tanys123, @papaponmx, @karlsander, @borekb, @michielvangendt, @rishabhpoddar, @enesakar, @ctbarna, @markkaylor, @stovmascript, @lucleray, @mvasilkov, @nyedidikeke, @mastoj, @janicklas-ralph, @ThangHuuVu, @Munawwar, @reod, @thomasmarshall, @AndreVarandas, @Ryz0nd, @qwertyforce, @samrobbins85, @brandonchinn178, @adam-cowley, @akellbl4, @jflayhart, @jaybekster, @stuymedova, @m-abdelwahab, @UniqueNL, @jamsinclair, @fabb, @abotsi, @kylemh, @JacobLey, @AryanBeezadhur, @afbarbaro, @javivelasco, @breyed, @roim, @mandarons, @stefanprobst, @sa3dany, @jarvelov, @apuyou, @gnbaron, @kaykdm, @michalbundyra, @brijendravarma, @tmcgann, @arturmuller, @noahweingand, @omasher, @yunger7, @raon0211, @noreiller, @shibe23, @enzoferey, @JeffersonBledsoe, @Timvdv, @smitssjors, @zackdotcomputer, @jameshoward, @tigger9flow, @sergioalvz, @tomchen, @kdy1, @zeekrey, @NickKelly1, @orta, @euess, @NickCrews, @ctjlewis, @delbaoliveira, @ahmedosama7450, @samsisle, and @mrmckeb for helping!