Skip to content

Commit 1005ee5

Browse files
authored
Prevent resizing the url of an image already resized (GitbookIO#2600)
1 parent d9bb9f9 commit 1005ee5

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

packages/gitbook/src/app/(global)/~gitbook/image/route.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import {
44
verifyImageSignature,
55
resizeImage,
66
CloudflareImageOptions,
7-
checkIsSizableImageURL,
87
imagesResizingSignVersion,
8+
checkIsSizableImageURL,
99
} from '@/lib/images';
1010
import { parseImageAPIURL } from '@/lib/urls';
1111

@@ -28,8 +28,10 @@ export async function GET(request: NextRequest) {
2828

2929
const url = parseImageAPIURL(urlParam);
3030

31-
// Prevent infinite loops
32-
if (url.includes('/~gitbook/image')) {
31+
// Check again if the image can be sized, even though we checked when rendering the Image component
32+
// Otherwise, it's possible to pass just any link to this endpoint and trigger HTML injection on the domain
33+
// Also prevent infinite redirects.
34+
if (!checkIsSizableImageURL(url)) {
3335
return new Response('Invalid url parameter', { status: 400 });
3436
}
3537

@@ -38,12 +40,6 @@ export async function GET(request: NextRequest) {
3840
return Response.redirect(url, 302);
3941
}
4042

41-
// Check again if the image can be sized, even though we checked when rendering the Image component
42-
// Otherwise, it's possible to pass just any link to this endpoint and trigger HTML injection on the domain
43-
if (!checkIsSizableImageURL(url)) {
44-
return new Response('Invalid url parameter', { status: 400 });
45-
}
46-
4743
// Verify the signature
4844
const verified = await verifyImageSignature(url, { signature });
4945
if (!verified) {

packages/gitbook/src/lib/images.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,26 @@ export function checkIsHttpURL(input: string | URL): boolean {
5555
* Check if an image URL is resizable.
5656
* Skip it for non-http(s) URLs (data, etc).
5757
* Skip it for SVGs.
58+
* Skip it for GitBook images (to avoid recursion).
5859
*/
5960
export function checkIsSizableImageURL(input: string): boolean {
6061
if (!URL.canParse(input)) {
6162
return false;
6263
}
6364

65+
if (input.includes('/~gitbook/image')) {
66+
return false;
67+
}
68+
6469
const parsed = new URL(input);
6570
if (parsed.pathname.endsWith('.svg')) {
6671
return false;
6772
}
68-
return checkIsHttpURL(parsed);
73+
if (!checkIsHttpURL(parsed)) {
74+
return false;
75+
}
76+
77+
return true;
6978
}
7079

7180
interface ResizeImageOptions {

0 commit comments

Comments
 (0)