diff --git a/packages/next/src/server/image-optimizer.ts b/packages/next/src/server/image-optimizer.ts index 7ad6f90be46e0..225fc3196d7b3 100644 --- a/packages/next/src/server/image-optimizer.ts +++ b/packages/next/src/server/image-optimizer.ts @@ -187,6 +187,22 @@ export class ImageOptimizerCache { return { errorMessage: '"url" parameter cannot be an array' } } + if (url.length > 3072) { + return { errorMessage: '"url" parameter is too long' } + } + + if (url.startsWith('//')) { + return { + errorMessage: '"url" parameter cannot be a protocol-relative URL (//)', + } + } + + if (url.startsWith('/_next/image')) { + return { + errorMessage: '"url" parameter cannot be recursive', + } + } + let isAbsolute: boolean if (url.startsWith('/')) { diff --git a/test/integration/image-optimizer/test/util.ts b/test/integration/image-optimizer/test/util.ts index 393930d1c6b13..f1fd063f837c0 100644 --- a/test/integration/image-optimizer/test/util.ts +++ b/test/integration/image-optimizer/test/util.ts @@ -863,6 +863,29 @@ export function runTests(ctx) { expect(await res.text()).toBe(`"url" parameter is invalid`) }) + it('should fail when url is too long', async () => { + const query = { url: `/${'a'.repeat(4000)}`, w: ctx.w, q: 1 } + const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, {}) + expect(res.status).toBe(400) + expect(await res.text()).toBe(`"url" parameter is too long`) + }) + + it('should fail when url is protocol relative', async () => { + const query = { url: `//example.com`, w: ctx.w, q: 1 } + const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, {}) + expect(res.status).toBe(400) + expect(await res.text()).toBe( + `"url" parameter cannot be a protocol-relative URL (//)` + ) + }) + + it('should fail when url is recursive', async () => { + const query = { url: `/_next/image?url=test.pngw=1&q=1`, w: ctx.w, q: 1 } + const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, {}) + expect(res.status).toBe(400) + expect(await res.text()).toBe(`"url" parameter cannot be recursive`) + }) + it('should fail when internal url is not an image', async () => { const url = `//

not-an-image

` const query = { url, w: ctx.w, q: 39 }