vercel / next.js

The React Framework
https://nextjs.org
MIT License
121.8k stars 26.05k forks source link

fix(next): reject protocol-relative URLs in image optimization #65752

Closed emmerich closed 2 weeks ago

emmerich commented 2 weeks ago

This PR introduces a breaking change that returns a 400 error if the Image Optimization API is given a protocol-relative URL.

The Image Optimization API currently checks whether the given image URL is relative by checking url.startsWith('/'). This means that protocol-relative URLs, such as //example.com, pass the check and are treated as relative. They in turn skip any kind of validation provided when matching against remotePatterns and are passed back to the optimation logic as a relative URL.

My knowledge of the stack stops there, but in our case at GitBook it led to a nasty attack where non-GitBook content could be served over this URL: https://docs.gitbook.com/_next/image?url=//example.com&w=1200&q=100 - even though we have configured remotePatterns to protect against it.

I originally went into the problem wanting to handle the URL properly (treating it as an absolute URL and potentially using the protocol of the Optimization API itself as the relative protocol), but after seeing the code in

https://github.com/vercel/next.js/blob/canary/packages/next/src/client/legacy/image.tsx#L135

and

https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/image-loader.ts#L26

it feels that protocol-relative URLs are just not really supported anywhere. My understanding is that very few uses of next/image will be allowed to use protocol-relative URLs, so the impact of this breaking change should be quite low? If others disagree I am happy to modify and to use the protocol of the request as a stand-in for the relative protocol.

ijjk commented 2 weeks ago

Allow CI Workflow Run

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

ijjk commented 2 weeks ago

Failing test suites

Commit: b9e7042b2ca753cf792602891cb0a2ac84842897

__NEXT_EXPERIMENTAL_PPR=true pnpm test-start test/e2e/app-dir/css-client-side-nav-parallel-routes/css-client-side-nav-parallel-routes.test.ts (PPR)

Expand output ● css-client-side-nav-parallel-routes › should apply styles after navigation expect(received).toBe(expected) // Object.is equality Expected: "rgb(0, 255, 0)" Received: "rgba(0, 0, 0, 0)" 12 | expect( 13 | await browser.elementByCss('#global').getComputedCss('background-color') > 14 | ).toBe('rgb(0, 255, 0)') | ^ 15 | expect( 16 | await browser.elementByCss('#module').getComputedCss('background-color') 17 | ).toBe('rgb(0, 255, 0)') at Object.toBe (e2e/app-dir/css-client-side-nav-parallel-routes/css-client-side-nav-parallel-routes.test.ts:14:7)

Read more about building and testing Next.js in contributing.md.

TURBOPACK=1 pnpm test-start test/e2e/prerender.test.ts (turbopack)

Expand output ● Prerender › should on-demand revalidate for fallback: blocking with onlyGenerated if generated expect(received).toMatch(expected) Expected pattern: /(HIT|STALE)/ Received string: "MISS" 2300 | 2301 | expect(initialTime).toBe($2('#time').text()) > 2302 | expect(res2.headers.get('x-nextjs-cache')).toMatch(/(HIT|STALE)/) | ^ 2303 | 2304 | const res3 = await fetchViaHTTP( 2305 | next.url, at Object.toMatch (e2e/prerender.test.ts:2302:52)

Read more about building and testing Next.js in contributing.md.

__NEXT_EXPERIMENTAL_PPR=true pnpm test-dev test/e2e/app-dir/actions-allowed-origins/app-action-allowed-origins.test.ts (PPR)

Expand output ● app-dir action allowed origins › should pass if localhost is set as a safe origin thrown: "Exceeded timeout of 120000 ms for a hook. Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." 252 | let next: NextInstance | undefined 253 | if (!skipped) { > 254 | beforeAll(async () => { | ^ 255 | next = await createNext(options) 256 | }) 257 | afterAll(async () => { at beforeAll (lib/e2e-utils.ts:254:5) at e2e/app-dir/actions-allowed-origins/app-action-allowed-origins.test.ts:6:42 at Object.describe (e2e/app-dir/actions-allowed-origins/app-action-allowed-origins.test.ts:5:1) ● Test suite failed to run thrown: "Exceeded timeout of 120000 ms for a hook. Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." 131 | 132 | if (typeof afterAll === 'function') { > 133 | afterAll(async () => { | ^ 134 | if (nextInstance) { 135 | await nextInstance.destroy() 136 | throw new Error( at Object.afterAll (lib/e2e-utils.ts:133:3) at Object. (e2e/app-dir/actions-allowed-origins/app-action-allowed-origins.test.ts:5:19)

Read more about building and testing Next.js in contributing.md.

ijjk commented 2 weeks ago

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️ | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | buildDuration | 16.8s | 14.1s | N/A | | buildDurationCached | 7.8s | 7.3s | N/A | | nodeModulesSize | 345 MB | 345 MB | ⚠️ +1.56 kB | | nextStartRea..uration (ms) | 411ms | 412ms | N/A |
Client Bundles (main, webpack) | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | 1813.HASH.js gzip | 169 B | 169 B | ✓ | | 3433-HASH.js gzip | 5.06 kB | 5.06 kB | N/A | | 6159-HASH.js gzip | 33.5 kB | 33.5 kB | N/A | | 69089819-HASH.js gzip | 50.8 kB | 50.8 kB | N/A | | framework-HASH.js gzip | 55.8 kB | 55.8 kB | N/A | | main-app-HASH.js gzip | 221 B | 221 B | ✓ | | main-HASH.js gzip | 32.3 kB | 32.3 kB | N/A | | webpack-HASH.js gzip | 1.71 kB | 1.7 kB | N/A | | Overall change | 390 B | 390 B | ✓ |
Legacy Client Bundles (polyfills) | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ | | Overall change | 31 kB | 31 kB | ✓ |
Client Pages | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | _app-HASH.js gzip | 192 B | 193 B | N/A | | _error-HASH.js gzip | 192 B | 192 B | ✓ | | amp-HASH.js gzip | 511 B | 510 B | N/A | | css-HASH.js gzip | 342 B | 343 B | N/A | | dynamic-HASH.js gzip | 2.53 kB | 2.52 kB | N/A | | edge-ssr-HASH.js gzip | 265 B | 266 B | N/A | | head-HASH.js gzip | 362 B | 364 B | N/A | | hooks-HASH.js gzip | 391 B | 392 B | N/A | | image-HASH.js gzip | 4.27 kB | 4.27 kB | N/A | | index-HASH.js gzip | 269 B | 268 B | N/A | | link-HASH.js gzip | 2.69 kB | 2.69 kB | N/A | | routerDirect..HASH.js gzip | 328 B | 329 B | N/A | | script-HASH.js gzip | 393 B | 397 B | N/A | | withRouter-HASH.js gzip | 325 B | 324 B | N/A | | 1afbb74e6ecf..834.css gzip | 106 B | 106 B | ✓ | | Overall change | 298 B | 298 B | ✓ |
Client Build Manifests | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | _buildManifest.js gzip | 482 B | 483 B | N/A | | Overall change | 0 B | 0 B | ✓ |
Rendered Page Sizes | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | index.html gzip | 521 B | 522 B | N/A | | link.html gzip | 535 B | 536 B | N/A | | withRouter.html gzip | 517 B | 517 B | ✓ | | Overall change | 517 B | 517 B | ✓ |
Edge SSR bundle Size | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | edge-ssr.js gzip | 120 kB | 120 kB | N/A | | page.js gzip | 179 kB | 179 kB | N/A | | Overall change | 0 B | 0 B | ✓ |
Middleware size | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | middleware-b..fest.js gzip | 655 B | 658 B | N/A | | middleware-r..fest.js gzip | 155 B | 153 B | N/A | | middleware.js gzip | 26 kB | 26 kB | N/A | | edge-runtime..pack.js gzip | 839 B | 839 B | ✓ | | Overall change | 839 B | 839 B | ✓ |
Next Runtimes | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | app-page-exp...dev.js gzip | 173 kB | 173 kB | ✓ | | app-page-exp..prod.js gzip | 105 kB | 105 kB | ✓ | | app-page-tur..prod.js gzip | 115 kB | 115 kB | ✓ | | app-page-tur..prod.js gzip | 94.2 kB | 94.2 kB | ✓ | | app-page.run...dev.js gzip | 159 kB | 159 kB | ✓ | | app-page.run..prod.js gzip | 92.9 kB | 92.9 kB | ✓ | | app-route-ex...dev.js gzip | 20.9 kB | 20.9 kB | ✓ | | app-route-ex..prod.js gzip | 14.9 kB | 14.9 kB | ✓ | | app-route-tu..prod.js gzip | 15 kB | 15 kB | ✓ | | app-route-tu..prod.js gzip | 14.8 kB | 14.8 kB | ✓ | | app-route.ru...dev.js gzip | 20.7 kB | 20.7 kB | ✓ | | app-route.ru..prod.js gzip | 14.8 kB | 14.8 kB | ✓ | | pages-api-tu..prod.js gzip | 9.53 kB | 9.53 kB | ✓ | | pages-api.ru...dev.js gzip | 9.8 kB | 9.8 kB | ✓ | | pages-api.ru..prod.js gzip | 9.53 kB | 9.53 kB | ✓ | | pages-turbo...prod.js gzip | 21.4 kB | 21.4 kB | ✓ | | pages.runtim...dev.js gzip | 22 kB | 22 kB | ✓ | | pages.runtim..prod.js gzip | 21.4 kB | 21.4 kB | ✓ | | server.runti..prod.js gzip | 51.8 kB | 51.8 kB | ✓ | | Overall change | 986 kB | 986 kB | ✓ |
build cache Overall increase ⚠️ | | vercel/next.js canary | emmerich/next.js emmerich/fix-protocol-relative-image-optimization | Change | | - | - | - | - | | 0.pack gzip | 1.64 MB | 1.64 MB | N/A | | index.pack gzip | 126 kB | 127 kB | ⚠️ +1.33 kB | | Overall change | 126 kB | 127 kB | ⚠️ +1.33 kB |
Diff details
Diff for page.js ```diff @@ -15,7 +15,7 @@ /***/ }, - /***/ 832: /***/ ( + /***/ 8712: /***/ ( __unused_webpack_module, __webpack_exports__, __webpack_require__ @@ -30,7 +30,7 @@ default: () => /* binding */ nHandler, }); - // NAMESPACE OBJECT: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statssfzin7%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__ + // NAMESPACE OBJECT: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statssfzin7%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__ var page_next_edge_ssr_entry_namespaceObject = {}; __webpack_require__.r(page_next_edge_ssr_entry_namespaceObject); __webpack_require__.d(page_next_edge_ssr_entry_namespaceObject, { @@ -68,24 +68,24 @@ tree: () => tree, }); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/web/globals.js - var globals = __webpack_require__(5107); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/web/adapter.js + 3 modules - var adapter = __webpack_require__(6713); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render.js + 87 modules - var render = __webpack_require__(6526); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/lib/incremental-cache/index.js + 3 modules - var incremental_cache = __webpack_require__(2116); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/app-render/app-render.js + 52 modules - var app_render = __webpack_require__(7906); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/future/route-modules/app-page/module.compiled.js - var module_compiled = __webpack_require__(4445); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/future/route-kind.js - var route_kind = __webpack_require__(8063); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/client/components/error-boundary.js - var error_boundary = __webpack_require__(3483); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/app-render/entry-base.js + 9 modules - var entry_base = __webpack_require__(7165); // CONCATENATED MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statssfzin7%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__ + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/web/globals.js + var globals = __webpack_require__(4009); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/web/adapter.js + 3 modules + var adapter = __webpack_require__(6978); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render.js + 87 modules + var render = __webpack_require__(8791); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/lib/incremental-cache/index.js + 3 modules + var incremental_cache = __webpack_require__(994); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/app-render/app-render.js + 52 modules + var app_render = __webpack_require__(3653); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/future/route-modules/app-page/module.compiled.js + var module_compiled = __webpack_require__(8414); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/future/route-kind.js + var route_kind = __webpack_require__(2229); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/client/components/error-boundary.js + var error_boundary = __webpack_require__(8002); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/app-render/entry-base.js + 9 modules + var entry_base = __webpack_require__(7832); // CONCATENATED MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-statssfzin7%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__ ("TURBOPACK { transition: next-ssr }"); // We inject the tree and pages here so that we can use them in the route @@ -104,7 +104,7 @@ page: [ () => Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 4791) + __webpack_require__.bind(__webpack_require__, 3053) ), "/tmp/next-statssfzin7/stats-app/app/app-edge-ssr/page.js", ], @@ -118,14 +118,14 @@ layout: [ () => Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 9469) + __webpack_require__.bind(__webpack_require__, 9363) ), "/tmp/next-statssfzin7/stats-app/app/layout.js", ], "not-found": [ () => Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 3048) + __webpack_require__.bind(__webpack_require__, 6385) ), "next/dist/client/components/not-found-error", ], @@ -161,12 +161,12 @@ }); //# sourceMappingURL=app-page.js.map - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/lib/page-types.js - var page_types = __webpack_require__(3047); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/app-render/encryption-utils.js - var encryption_utils = __webpack_require__(866); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/esm/server/app-render/action-utils.js - var action_utils = __webpack_require__(2041); // CONCATENATED MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/dist/build/webpack/loaders/next-edge-ssr-loader/index.js?{"absolute500Path":"","absoluteAppPath":"next/dist/pages/_app","absoluteDocumentPath":"next/dist/pages/_document","absoluteErrorPath":"next/dist/pages/_error","absolutePagePath":"private-next-app-dir/app-edge-ssr/page.js","dev":false,"isServerComponent":true,"page":"/app-edge-ssr/page","stringifiedConfig":"eyJlbnYiOnt9LCJlc2xpbnQiOnsiaWdub3JlRHVyaW5nQnVpbGRzIjpmYWxzZX0sInR5cGVzY3JpcHQiOnsiaWdub3JlQnVpbGRFcnJvcnMiOmZhbHNlLCJ0c2NvbmZpZ1BhdGgiOiJ0c2NvbmZpZy5qc29uIn0sImRpc3REaXIiOiIubmV4dCIsImNsZWFuRGlzdERpciI6dHJ1ZSwiYXNzZXRQcmVmaXgiOiIiLCJjYWNoZU1heE1lbW9yeVNpemUiOjUyNDI4ODAwLCJjb25maWdPcmlnaW4iOiJuZXh0LmNvbmZpZy5qcyIsInVzZUZpbGVTeXN0ZW1QdWJsaWNSb3V0ZXMiOnRydWUsImdlbmVyYXRlRXRhZ3MiOnRydWUsInBhZ2VFeHRlbnNpb25zIjpbInRzeCIsInRzIiwianN4IiwianMiXSwicG93ZXJlZEJ5SGVhZGVyIjp0cnVlLCJjb21wcmVzcyI6dHJ1ZSwiaW1hZ2VzIjp7ImRldmljZVNpemVzIjpbNjQwLDc1MCw4MjgsMTA4MCwxMjAwLDE5MjAsMjA0OCwzODQwXSwiaW1hZ2VTaXplcyI6WzE2LDMyLDQ4LDY0LDk2LDEyOCwyNTYsMzg0XSwicGF0aCI6Ii9fbmV4dC9pbWFnZSIsImxvYWRlciI6ImRlZmF1bHQiLCJsb2FkZXJGaWxlIjoiIiwiZG9tYWlucyI6W10sImRpc2FibGVTdGF0aWNJbWFnZXMiOmZhbHNlLCJtaW5pbXVtQ2FjaGVUVEwiOjYwLCJmb3JtYXRzIjpbImltYWdlL3dlYnAiXSwiZGFuZ2Vyb3VzbHlBbGxvd1NWRyI6ZmFsc2UsImNvbnRlbnRTZWN1cml0eVBvbGljeSI6InNjcmlwdC1zcmMgJ25vbmUnOyBmcmFtZS1zcmMgJ25vbmUnOyBzYW5kYm94OyIsImNvbnRlbnREaXNwb3NpdGlvblR5cGUiOiJhdHRhY2htZW50IiwicmVtb3RlUGF0dGVybnMiOltdLCJ1bm9wdGltaXplZCI6ZmFsc2V9LCJkZXZJbmRpY2F0b3JzIjp7ImJ1aWxkQWN0aXZpdHkiOnRydWUsImJ1aWxkQWN0aXZpdHlQb3NpdGlvbiI6ImJvdHRvbS1yaWdodCJ9LCJvbkRlbWFuZEVudHJpZXMiOnsibWF4SW5hY3RpdmVBZ2UiOjYwMDAwLCJwYWdlc0J1ZmZlckxlbmd0aCI6NX0sImFtcCI6eyJjYW5vbmljYWxCYXNlIjoiIn0sImJhc2VQYXRoIjoiIiwic2Fzc09wdGlvbnMiOnt9LCJ0cmFpbGluZ1NsYXNoIjpmYWxzZSwiaTE4biI6bnVsbCwicHJvZHVjdGlvbkJyb3dzZXJTb3VyY2VNYXBzIjpmYWxzZSwib3B0aW1pemVGb250cyI6dHJ1ZSwiZXhjbHVkZURlZmF1bHRNb21lbnRMb2NhbGVzIjp0cnVlLCJzZXJ2ZXJSdW50aW1lQ29uZmlnIjp7fSwicHVibGljUnVudGltZUNvbmZpZyI6e30sInJlYWN0UHJvZHVjdGlvblByb2ZpbGluZyI6ZmFsc2UsInJlYWN0U3RyaWN0TW9kZSI6bnVsbCwiaHR0cEFnZW50T3B0aW9ucyI6eyJrZWVwQWxpdmUiOnRydWV9LCJzdGF0aWNQYWdlR2VuZXJhdGlvblRpbWVvdXQiOjYwLCJtb2R1bGFyaXplSW1wb3J0cyI6eyJAbXVpL2ljb25zLW1hdGVyaWFsIjp7InRyYW5zZm9ybSI6IkBtdWkvaWNvbnMtbWF0ZXJpYWwve3ttZW1iZXJ9fSJ9LCJsb2Rhc2giOnsidHJhbnNmb3JtIjoibG9kYXNoL3t7bWVtYmVyfX0ifX0sImV4cGVyaW1lbnRhbCI6eyJmbHlpbmdTaHV0dGxlIjpmYWxzZSwicHJlcmVuZGVyRWFybHlFeGl0IjpmYWxzZSwic2VydmVyTWluaWZpY2F0aW9uIjp0cnVlLCJzZXJ2ZXJTb3VyY2VNYXBzIjpmYWxzZSwibGlua05vVG91Y2hTdGFydCI6ZmFsc2UsImNhc2VTZW5zaXRpdmVSb3V0ZXMiOmZhbHNlLCJwcmVsb2FkRW50cmllc09uU3RhcnQiOnRydWUsImNsaWVudFJvdXRlckZpbHRlciI6dHJ1ZSwiY2xpZW50Um91dGVyRmlsdGVyUmVkaXJlY3RzIjpmYWxzZSwiZmV0Y2hDYWNoZUtleVByZWZpeCI6IiIsIm1pZGRsZXdhcmVQcmVmZXRjaCI6ImZsZXhpYmxlIiwib3B0aW1pc3RpY0NsaWVudENhY2hlIjp0cnVlLCJtYW51YWxDbGllbnRCYXNlUGF0aCI6ZmFsc2UsImNwdXMiOjE5LCJtZW1vcnlCYXNlZFdvcmtlcnNDb3VudCI6ZmFsc2UsImlzckZsdXNoVG9EaXNrIjp0cnVlLCJ3b3JrZXJUaHJlYWRzIjpmYWxzZSwib3B0aW1pemVDc3MiOmZhbHNlLCJuZXh0U2NyaXB0V29ya2VycyI6ZmFsc2UsInNjcm9sbFJlc3RvcmF0aW9uIjpmYWxzZSwiZXh0ZXJuYWxEaXIiOmZhbHNlLCJkaXNhYmxlT3B0aW1pemVkTG9hZGluZyI6ZmFsc2UsImd6aXBTaXplIjp0cnVlLCJjcmFDb21wYXQiOmZhbHNlLCJlc21FeHRlcm5hbHMiOnRydWUsImZ1bGx5U3BlY2lmaWVkIjpmYWxzZSwib3V0cHV0RmlsZVRyYWNpbmdSb290IjoiL3RtcC9uZXh0LXN0YXRzc2Z6aW43L3N0YXRzLWFwcCIsInN3Y1RyYWNlUHJvZmlsaW5nIjpmYWxzZSwiZm9yY2VTd2NUcmFuc2Zvcm1zIjpmYWxzZSwibGFyZ2VQYWdlRGF0YUJ5dGVzIjoxMjgwMDAsImFkanVzdEZvbnRGYWxsYmFja3MiOmZhbHNlLCJhZGp1c3RGb250RmFsbGJhY2tzV2l0aFNpemVBZGp1c3QiOmZhbHNlLCJ0eXBlZFJvdXRlcyI6ZmFsc2UsImluc3RydW1lbnRhdGlvbkhvb2siOmZhbHNlLCJwYXJhbGxlbFNlcnZlckNvbXBpbGVzIjpmYWxzZSwicGFyYWxsZWxTZXJ2ZXJCdWlsZFRyYWNlcyI6ZmFsc2UsInBwciI6ZmFsc2UsIm9wdGltaXplU2VydmVyUmVhY3QiOnRydWUsInVzZUVhcmx5SW1wb3J0IjpmYWxzZSwic3RhbGVUaW1lcyI6eyJkeW5hbWljIjozMCwic3RhdGljIjozMDB9LCJvcHRpbWl6ZVBhY2thZ2VJbXBvcnRzIjpbImx1Y2lkZS1yZWFjdCIsImRhdGUtZm5zIiwibG9kYXNoLWVzIiwicmFtZGEiLCJhbnRkIiwicmVhY3QtYm9vdHN0cmFwIiwiYWhvb2tzIiwiQGFudC1kZXNpZ24vaWNvbnMiLCJAaGVhZGxlc3N1aS9yZWFjdCIsIkBoZWFkbGVzc3VpLWZsb2F0L3JlYWN0IiwiQGhlcm9pY29ucy9yZWFjdC8yMC9zb2xpZCIsIkBoZXJvaWNvbnMvcmVhY3QvMjQvc29saWQiLCJAaGVyb2ljb25zL3JlYWN0LzI0L291dGxpbmUiLCJAdmlzeC92aXN4IiwiQHRyZW1vci9yZWFjdCIsInJ4anMiLCJAbXVpL21hdGVyaWFsIiwiQG11aS9pY29ucy1tYXRlcmlhbCIsInJlY2hhcnRzIiwicmVhY3QtdXNlIiwiQG1hdGVyaWFsLXVpL2NvcmUiLCJAbWF0ZXJpYWwtdWkvaWNvbnMiLCJAdGFibGVyL2ljb25zLXJlYWN0IiwibXVpLWNvcmUiLCJyZWFjdC1pY29ucy9haSIsInJlYWN0LWljb25zL2JpIiwicmVhY3QtaWNvbnMvYnMiLCJyZWFjdC1pY29ucy9jZyIsInJlYWN0LWljb25zL2NpIiwicmVhY3QtaWNvbnMvZGkiLCJyZWFjdC1pY29ucy9mYSIsInJlYWN0LWljb25zL2ZhNiIsInJlYWN0LWljb25zL2ZjIiwicmVhY3QtaWNvbnMvZmkiLCJyZWFjdC1pY29ucy9naSIsInJlYWN0LWljb25zL2dvIiwicmVhY3QtaWNvbnMvZ3IiLCJyZWFjdC1pY29ucy9oaSIsInJlYWN0LWljb25zL2hpMiIsInJlYWN0LWljb25zL2ltIiwicmVhY3QtaWNvbnMvaW8iLCJyZWFjdC1pY29ucy9pbzUiLCJyZWFjdC1pY29ucy9saWEiLCJyZWFjdC1pY29ucy9saWIiLCJyZWFjdC1pY29ucy9sdSIsInJlYWN0LWljb25zL21kIiwicmVhY3QtaWNvbnMvcGkiLCJyZWFjdC1pY29ucy9yaSIsInJlYWN0LWljb25zL3J4IiwicmVhY3QtaWNvbnMvc2kiLCJyZWFjdC1pY29ucy9zbCIsInJlYWN0LWljb25zL3RiIiwicmVhY3QtaWNvbnMvdGZpIiwicmVhY3QtaWNvbnMvdGkiLCJyZWFjdC1pY29ucy92c2MiLCJyZWFjdC1pY29ucy93aSJdfSwiYnVuZGxlUGFnZXNSb3V0ZXJEZXBlbmRlbmNpZXMiOmZhbHNlLCJjb25maWdGaWxlIjoiL3RtcC9uZXh0LXN0YXRzc2Z6aW43L3N0YXRzLWFwcC9uZXh0LmNvbmZpZy5qcyIsImNvbmZpZ0ZpbGVOYW1lIjoibmV4dC5jb25maWcuanMifQ==","pagesType":"app","appDirLoader":"bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBwLWVkZ2Utc3NyJTJGcGFnZSZwYWdlPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcHAtZWRnZS1zc3IlMkZwYWdlLmpzJmFwcERpcj0lMkZ0bXAlMkZuZXh0LXN0YXRzc2Z6aW43JTJGc3RhdHMtYXBwJTJGYXBwJmFwcFBhdGhzPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JnByZWZlcnJlZFJlZ2lvbj0mbWlkZGxld2FyZUNvbmZpZz1lMzAlM0Qh","sriEnabled":false,"middlewareConfig":"e30="}! + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/lib/page-types.js + var page_types = __webpack_require__(9287); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/app-render/encryption-utils.js + var encryption_utils = __webpack_require__(3934); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/esm/server/app-render/action-utils.js + var action_utils = __webpack_require__(1730); // CONCATENATED MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/dist/build/webpack/loaders/next-edge-ssr-loader/index.js?{"absolute500Path":"","absoluteAppPath":"next/dist/pages/_app","absoluteDocumentPath":"next/dist/pages/_document","absoluteErrorPath":"next/dist/pages/_error","absolutePagePath":"private-next-app-dir/app-edge-ssr/page.js","dev":false,"isServerComponent":true,"page":"/app-edge-ssr/page","stringifiedConfig":"eyJlbnYiOnt9LCJlc2xpbnQiOnsiaWdub3JlRHVyaW5nQnVpbGRzIjpmYWxzZX0sInR5cGVzY3JpcHQiOnsiaWdub3JlQnVpbGRFcnJvcnMiOmZhbHNlLCJ0c2NvbmZpZ1BhdGgiOiJ0c2NvbmZpZy5qc29uIn0sImRpc3REaXIiOiIubmV4dCIsImNsZWFuRGlzdERpciI6dHJ1ZSwiYXNzZXRQcmVmaXgiOiIiLCJjYWNoZU1heE1lbW9yeVNpemUiOjUyNDI4ODAwLCJjb25maWdPcmlnaW4iOiJuZXh0LmNvbmZpZy5qcyIsInVzZUZpbGVTeXN0ZW1QdWJsaWNSb3V0ZXMiOnRydWUsImdlbmVyYXRlRXRhZ3MiOnRydWUsInBhZ2VFeHRlbnNpb25zIjpbInRzeCIsInRzIiwianN4IiwianMiXSwicG93ZXJlZEJ5SGVhZGVyIjp0cnVlLCJjb21wcmVzcyI6dHJ1ZSwiaW1hZ2VzIjp7ImRldmljZVNpemVzIjpbNjQwLDc1MCw4MjgsMTA4MCwxMjAwLDE5MjAsMjA0OCwzODQwXSwiaW1hZ2VTaXplcyI6WzE2LDMyLDQ4LDY0LDk2LDEyOCwyNTYsMzg0XSwicGF0aCI6Ii9fbmV4dC9pbWFnZSIsImxvYWRlciI6ImRlZmF1bHQiLCJsb2FkZXJGaWxlIjoiIiwiZG9tYWlucyI6W10sImRpc2FibGVTdGF0aWNJbWFnZXMiOmZhbHNlLCJtaW5pbXVtQ2FjaGVUVEwiOjYwLCJmb3JtYXRzIjpbImltYWdlL3dlYnAiXSwiZGFuZ2Vyb3VzbHlBbGxvd1NWRyI6ZmFsc2UsImNvbnRlbnRTZWN1cml0eVBvbGljeSI6InNjcmlwdC1zcmMgJ25vbmUnOyBmcmFtZS1zcmMgJ25vbmUnOyBzYW5kYm94OyIsImNvbnRlbnREaXNwb3NpdGlvblR5cGUiOiJhdHRhY2htZW50IiwicmVtb3RlUGF0dGVybnMiOltdLCJ1bm9wdGltaXplZCI6ZmFsc2V9LCJkZXZJbmRpY2F0b3JzIjp7ImJ1aWxkQWN0aXZpdHkiOnRydWUsImJ1aWxkQWN0aXZpdHlQb3NpdGlvbiI6ImJvdHRvbS1yaWdodCJ9LCJvbkRlbWFuZEVudHJpZXMiOnsibWF4SW5hY3RpdmVBZ2UiOjYwMDAwLCJwYWdlc0J1ZmZlckxlbmd0aCI6NX0sImFtcCI6eyJjYW5vbmljYWxCYXNlIjoiIn0sImJhc2VQYXRoIjoiIiwic2Fzc09wdGlvbnMiOnt9LCJ0cmFpbGluZ1NsYXNoIjpmYWxzZSwiaTE4biI6bnVsbCwicHJvZHVjdGlvbkJyb3dzZXJTb3VyY2VNYXBzIjpmYWxzZSwib3B0aW1pemVGb250cyI6dHJ1ZSwiZXhjbHVkZURlZmF1bHRNb21lbnRMb2NhbGVzIjp0cnVlLCJzZXJ2ZXJSdW50aW1lQ29uZmlnIjp7fSwicHVibGljUnVudGltZUNvbmZpZyI6e30sInJlYWN0UHJvZHVjdGlvblByb2ZpbGluZyI6ZmFsc2UsInJlYWN0U3RyaWN0TW9kZSI6bnVsbCwiaHR0cEFnZW50T3B0aW9ucyI6eyJrZWVwQWxpdmUiOnRydWV9LCJzdGF0aWNQYWdlR2VuZXJhdGlvblRpbWVvdXQiOjYwLCJtb2R1bGFyaXplSW1wb3J0cyI6eyJAbXVpL2ljb25zLW1hdGVyaWFsIjp7InRyYW5zZm9ybSI6IkBtdWkvaWNvbnMtbWF0ZXJpYWwve3ttZW1iZXJ9fSJ9LCJsb2Rhc2giOnsidHJhbnNmb3JtIjoibG9kYXNoL3t7bWVtYmVyfX0ifX0sImV4cGVyaW1lbnRhbCI6eyJmbHlpbmdTaHV0dGxlIjpmYWxzZSwicHJlcmVuZGVyRWFybHlFeGl0IjpmYWxzZSwic2VydmVyTWluaWZpY2F0aW9uIjp0cnVlLCJzZXJ2ZXJTb3VyY2VNYXBzIjpmYWxzZSwibGlua05vVG91Y2hTdGFydCI6ZmFsc2UsImNhc2VTZW5zaXRpdmVSb3V0ZXMiOmZhbHNlLCJwcmVsb2FkRW50cmllc09uU3RhcnQiOnRydWUsImNsaWVudFJvdXRlckZpbHRlciI6dHJ1ZSwiY2xpZW50Um91dGVyRmlsdGVyUmVkaXJlY3RzIjpmYWxzZSwiZmV0Y2hDYWNoZUtleVByZWZpeCI6IiIsIm1pZGRsZXdhcmVQcmVmZXRjaCI6ImZsZXhpYmxlIiwib3B0aW1pc3RpY0NsaWVudENhY2hlIjp0cnVlLCJtYW51YWxDbGllbnRCYXNlUGF0aCI6ZmFsc2UsImNwdXMiOjE5LCJtZW1vcnlCYXNlZFdvcmtlcnNDb3VudCI6ZmFsc2UsImlzckZsdXNoVG9EaXNrIjp0cnVlLCJ3b3JrZXJUaHJlYWRzIjpmYWxzZSwib3B0aW1pemVDc3MiOmZhbHNlLCJuZXh0U2NyaXB0V29ya2VycyI6ZmFsc2UsInNjcm9sbFJlc3RvcmF0aW9uIjpmYWxzZSwiZXh0ZXJuYWxEaXIiOmZhbHNlLCJkaXNhYmxlT3B0aW1pemVkTG9hZGluZyI6ZmFsc2UsImd6aXBTaXplIjp0cnVlLCJjcmFDb21wYXQiOmZhbHNlLCJlc21FeHRlcm5hbHMiOnRydWUsImZ1bGx5U3BlY2lmaWVkIjpmYWxzZSwib3V0cHV0RmlsZVRyYWNpbmdSb290IjoiL3RtcC9uZXh0LXN0YXRzc2Z6aW43L3N0YXRzLWFwcCIsInN3Y1RyYWNlUHJvZmlsaW5nIjpmYWxzZSwiZm9yY2VTd2NUcmFuc2Zvcm1zIjpmYWxzZSwibGFyZ2VQYWdlRGF0YUJ5dGVzIjoxMjgwMDAsImFkanVzdEZvbnRGYWxsYmFja3MiOmZhbHNlLCJhZGp1c3RGb250RmFsbGJhY2tzV2l0aFNpemVBZGp1c3QiOmZhbHNlLCJ0eXBlZFJvdXRlcyI6ZmFsc2UsImluc3RydW1lbnRhdGlvbkhvb2siOmZhbHNlLCJwYXJhbGxlbFNlcnZlckNvbXBpbGVzIjpmYWxzZSwicGFyYWxsZWxTZXJ2ZXJCdWlsZFRyYWNlcyI6ZmFsc2UsInBwciI6ZmFsc2UsIm9wdGltaXplU2VydmVyUmVhY3QiOnRydWUsInVzZUVhcmx5SW1wb3J0IjpmYWxzZSwic3RhbGVUaW1lcyI6eyJkeW5hbWljIjozMCwic3RhdGljIjozMDB9LCJvcHRpbWl6ZVBhY2thZ2VJbXBvcnRzIjpbImx1Y2lkZS1yZWFjdCIsImRhdGUtZm5zIiwibG9kYXNoLWVzIiwicmFtZGEiLCJhbnRkIiwicmVhY3QtYm9vdHN0cmFwIiwiYWhvb2tzIiwiQGFudC1kZXNpZ24vaWNvbnMiLCJAaGVhZGxlc3N1aS9yZWFjdCIsIkBoZWFkbGVzc3VpLWZsb2F0L3JlYWN0IiwiQGhlcm9pY29ucy9yZWFjdC8yMC9zb2xpZCIsIkBoZXJvaWNvbnMvcmVhY3QvMjQvc29saWQiLCJAaGVyb2ljb25zL3JlYWN0LzI0L291dGxpbmUiLCJAdmlzeC92aXN4IiwiQHRyZW1vci9yZWFjdCIsInJ4anMiLCJAbXVpL21hdGVyaWFsIiwiQG11aS9pY29ucy1tYXRlcmlhbCIsInJlY2hhcnRzIiwicmVhY3QtdXNlIiwiQG1hdGVyaWFsLXVpL2NvcmUiLCJAbWF0ZXJpYWwtdWkvaWNvbnMiLCJAdGFibGVyL2ljb25zLXJlYWN0IiwibXVpLWNvcmUiLCJyZWFjdC1pY29ucy9haSIsInJlYWN0LWljb25zL2JpIiwicmVhY3QtaWNvbnMvYnMiLCJyZWFjdC1pY29ucy9jZyIsInJlYWN0LWljb25zL2NpIiwicmVhY3QtaWNvbnMvZGkiLCJyZWFjdC1pY29ucy9mYSIsInJlYWN0LWljb25zL2ZhNiIsInJlYWN0LWljb25zL2ZjIiwicmVhY3QtaWNvbnMvZmkiLCJyZWFjdC1pY29ucy9naSIsInJlYWN0LWljb25zL2dvIiwicmVhY3QtaWNvbnMvZ3IiLCJyZWFjdC1pY29ucy9oaSIsInJlYWN0LWljb25zL2hpMiIsInJlYWN0LWljb25zL2ltIiwicmVhY3QtaWNvbnMvaW8iLCJyZWFjdC1pY29ucy9pbzUiLCJyZWFjdC1pY29ucy9saWEiLCJyZWFjdC1pY29ucy9saWIiLCJyZWFjdC1pY29ucy9sdSIsInJlYWN0LWljb25zL21kIiwicmVhY3QtaWNvbnMvcGkiLCJyZWFjdC1pY29ucy9yaSIsInJlYWN0LWljb25zL3J4IiwicmVhY3QtaWNvbnMvc2kiLCJyZWFjdC1pY29ucy9zbCIsInJlYWN0LWljb25zL3RiIiwicmVhY3QtaWNvbnMvdGZpIiwicmVhY3QtaWNvbnMvdGkiLCJyZWFjdC1pY29ucy92c2MiLCJyZWFjdC1pY29ucy93aSJdfSwiYnVuZGxlUGFnZXNSb3V0ZXJEZXBlbmRlbmNpZXMiOmZhbHNlLCJjb25maWdGaWxlIjoiL3RtcC9uZXh0LXN0YXRzc2Z6aW43L3N0YXRzLWFwcC9uZXh0LmNvbmZpZy5qcyIsImNvbmZpZ0ZpbGVOYW1lIjoibmV4dC5jb25maWcuanMifQ==","pagesType":"app","appDirLoader":"bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBwLWVkZ2Utc3NyJTJGcGFnZSZwYWdlPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcHAtZWRnZS1zc3IlMkZwYWdlLmpzJmFwcERpcj0lMkZ0bXAlMkZuZXh0LXN0YXRzc2Z6aW43JTJGc3RhdHMtYXBwJTJGYXBwJmFwcFBhdGhzPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JnByZWZlcnJlZFJlZ2lvbj0mbWlkZGxld2FyZUNvbmZpZz1lMzAlM0Qh","sriEnabled":false,"middlewareConfig":"e30="}! var _self___RSC_MANIFEST; const incrementalCacheHandler = null; @@ -404,47 +404,47 @@ /***/ }, - /***/ 6424: /***/ ( + /***/ 3816: /***/ ( __unused_webpack_module, __unused_webpack_exports, __webpack_require__ ) => { Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 1817) + __webpack_require__.bind(__webpack_require__, 4394) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 9652) + __webpack_require__.bind(__webpack_require__, 4988) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 3519) + __webpack_require__.bind(__webpack_require__, 9932) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 4977) + __webpack_require__.bind(__webpack_require__, 6371) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 9558) + __webpack_require__.bind(__webpack_require__, 9592) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 2096) + __webpack_require__.bind(__webpack_require__, 2380) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 9388) + __webpack_require__.bind(__webpack_require__, 6487) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 9693) + __webpack_require__.bind(__webpack_require__, 7202) ); Promise.resolve(/* import() eager */).then( - __webpack_require__.bind(__webpack_require__, 5675) + __webpack_require__.bind(__webpack_require__, 4645) ); /***/ }, - /***/ 7129: /***/ () => { + /***/ 8402: /***/ () => { /***/ }, - /***/ 4791: /***/ ( + /***/ 3053: /***/ ( __unused_webpack_module, __webpack_exports__, __webpack_require__ @@ -464,7 +464,7 @@ /***/ }, - /***/ 9469: /***/ ( + /***/ 9363: /***/ ( __unused_webpack_module, __webpack_exports__, __webpack_require__ @@ -476,7 +476,7 @@ /* harmony export */ }); /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = - __webpack_require__(3251); + __webpack_require__(4470); function RootLayout({ children }) { return /*#__PURE__*/ (0, @@ -495,7 +495,7 @@ // webpackRuntimeModules /******/ var __webpack_exec__ = (moduleId) => __webpack_require__((__webpack_require__.s = moduleId)); - /******/ __webpack_require__.O(0, [33, 320], () => __webpack_exec__(832)); + /******/ __webpack_require__.O(0, [778, 793], () => __webpack_exec__(8712)); /******/ var __webpack_exports__ = __webpack_require__.O(); /******/ (_ENTRIES = typeof _ENTRIES === "undefined" ? {} : _ENTRIES)[ "middleware_app/app-edge-ssr/page" ```
Diff for middleware.js Diff too large to display
Diff for edge-ssr.js Diff too large to display
Diff for image-HASH.js ```diff @@ -1,7 +1,7 @@ (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([ [8358], { - /***/ 5497: /***/ ( + /***/ 2307: /***/ ( __unused_webpack_module, __unused_webpack_exports, __webpack_require__ @@ -9,7 +9,7 @@ (window.__NEXT_P = window.__NEXT_P || []).push([ "/image", function () { - return __webpack_require__(5700); + return __webpack_require__(4720); }, ]); if (false) { @@ -18,7 +18,7 @@ /***/ }, - /***/ 959: /***/ (module, exports, __webpack_require__) => { + /***/ 8697: /***/ (module, exports, __webpack_require__) => { "use strict"; /* __next_internal_client_entry_do_not_use__ cjs */ Object.defineProperty(exports, "__esModule", { @@ -40,15 +40,15 @@ __webpack_require__(5439) ); const _head = /*#__PURE__*/ _interop_require_default._( - __webpack_require__(232) + __webpack_require__(2185) ); - const _getimgprops = __webpack_require__(7335); - const _imageconfig = __webpack_require__(7712); - const _imageconfigcontextsharedruntime = __webpack_require__(1207); - const _warnonce = __webpack_require__(9114); - const _routercontextsharedruntime = __webpack_require__(8426); + const _getimgprops = __webpack_require__(9461); + const _imageconfig = __webpack_require__(5517); + const _imageconfigcontextsharedruntime = __webpack_require__(8947); + const _warnonce = __webpack_require__(5860); + const _routercontextsharedruntime = __webpack_require__(7328); const _imageloader = /*#__PURE__*/ _interop_require_default._( - __webpack_require__(8106) + __webpack_require__(7310) ); // This is replaced by webpack define plugin const configEnv = { @@ -376,7 +376,7 @@ /***/ }, - /***/ 7335: /***/ ( + /***/ 9461: /***/ ( __unused_webpack_module, exports, __webpack_require__ @@ -392,9 +392,9 @@ return getImgProps; }, }); - const _warnonce = __webpack_require__(9114); - const _imageblursvg = __webpack_require__(9966); - const _imageconfig = __webpack_require__(7712); + const _warnonce = __webpack_require__(5860); + const _imageblursvg = __webpack_require__(5425); + const _imageconfig = __webpack_require__(5517); const VALID_LOADING_VALUES = /* unused pure expression or super */ null && [ "lazy", @@ -769,7 +769,7 @@ /***/ }, - /***/ 9966: /***/ (__unused_webpack_module, exports) => { + /***/ 5425: /***/ (__unused_webpack_module, exports) => { "use strict"; /** * A shared function, used on both client and server, to generate a SVG blur placeholder. @@ -824,7 +824,7 @@ /***/ }, - /***/ 8366: /***/ ( + /***/ 9578: /***/ ( __unused_webpack_module, exports, __webpack_require__ @@ -851,10 +851,10 @@ }, }); const _interop_require_default = __webpack_require__(1478); - const _getimgprops = __webpack_require__(7335); - const _imagecomponent = __webpack_require__(959); + const _getimgprops = __webpack_require__(9461); + const _imagecomponent = __webpack_require__(8697); const _imageloader = /*#__PURE__*/ _interop_require_default._( - __webpack_require__(8106) + __webpack_require__(7310) ); function getImageProps(imgProps) { const { props } = (0, _getimgprops.getImgProps)(imgProps, { @@ -886,7 +886,7 @@ /***/ }, - /***/ 8106: /***/ (__unused_webpack_module, exports) => { + /***/ 7310: /***/ (__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", { @@ -921,7 +921,7 @@ /***/ }, - /***/ 5700: /***/ ( + /***/ 4720: /***/ ( __unused_webpack_module, __webpack_exports__, __webpack_require__ @@ -938,8 +938,8 @@ // EXTERNAL MODULE: ./node_modules/.pnpm/react@19.0.0-beta-4508873393-20240430/node_modules/react/jsx-runtime.js var jsx_runtime = __webpack_require__(3456); - // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_65yyqpgvftv4sckwrae5ytuiki/node_modules/next/image.js - var next_image = __webpack_require__(5008); + // EXTERNAL MODULE: ./node_modules/.pnpm/file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-beta-4508873393-20240430_rea_bi4li5t763kdoqq4snruxkmfcu/node_modules/next/image.js + var next_image = __webpack_require__(932); var image_default = /*#__PURE__*/ __webpack_require__.n(next_image); // CONCATENATED MODULE: ./pages/nextjs.png /* harmony default export */ const nextjs = { src: "/_next/static/media/nextjs.cae0b805.png", @@ -969,12 +969,12 @@ /***/ }, - /***/ 5008: /***/ ( + /***/ 932: /***/ ( module, __unused_webpack_exports, __webpack_require__ ) => { - module.exports = __webpack_require__(8366); + module.exports = __webpack_require__(9578); /***/ }, @@ -984,7 +984,7 @@ /******/ var __webpack_exec__ = (moduleId) => __webpack_require__((__webpack_require__.s = moduleId)); /******/ __webpack_require__.O(0, [2888, 9774, 179], () => - __webpack_exec__(5497) + __webpack_exec__(2307) ); /******/ var __webpack_exports__ = __webpack_require__.O(); /******/ _N_E = __webpack_exports__; ```
Diff for main-HASH.js Diff too large to display

Commit: b9e7042b2ca753cf792602891cb0a2ac84842897

styfle commented 2 weeks ago

@emmerich One thing I don't understand is how the url your shared could serve html at all.

I can't reproduce this. Instead, I see Unable to optimize image and unable to fallback to upstream image when I run next dev without remotePatterns configured.

Is there specific config that would cause it to serve html instead of 400? Or perhaps this is only impacting older versions of Next.js and is already fixed in the latest version?

emmerich commented 2 weeks ago

@emmerich One thing I don't understand is how the url your shared could serve html at all.

I can't reproduce this. Instead, I see Unable to optimize image and unable to fallback to upstream image when I run next dev without remotePatterns configured.

Is there specific config that would cause it to serve html instead of 400? Or perhaps this is only impacting older versions of Next.js and is already fixed in the latest version?

@styfle I'm also a bit baffled by it. Our Next config is fairly straight-forward:

module.exports = {
        env: { ... },
        webpack() { ... },
        assetPrefix: process.env.GITBOOK_ASSETS_PREFIX, // GitBook static assets CDN
        poweredByHeader: false,

        images: {
            remotePatterns: [
                {
                    protocol: 'https',
                    hostname: '*.gitbook.io',
                    port: ''
                }
            ]
        }
}

Maybe a couple things to note:

We're on Next 14.1.3, so not an old version.

I suppose it could be something related to the combination of Cloudflare Pages, next-on-pages, and Nextjs that causes the endpoint to serve HTML, but I didn't dig deeper into next-server.

styfle commented 2 weeks ago

It looks like the issue only reproduces with Cloudflare Pages, not with next dev or next start.

This is likely a vulnerability in the custom Cloudflare code and not Next.js

Its probably best to contact them to get a more complete fix.

emmerich commented 2 weeks ago

After some digging in Cloudflare's next-on-pages project I've found that it has been fixed in a recent release: https://github.com/cloudflare/next-on-pages/commit/8da9da2535356836a7091776d5be84c80cc8091d

Thanks for the help @styfle !