Skip to content

Commit

Permalink
use ip check wrapper on img proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
JFrankfurt committed Oct 9, 2024
1 parent 0b42cce commit 514acd1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 43 deletions.
5 changes: 4 additions & 1 deletion apps/web/app/frames/img-proxy/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { withIPCheck } from 'apps/web/app/frames/proxy-ip-check';
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
export async function getHandler(request: NextRequest) {
const { searchParams } = new URL(request.url);
const url = searchParams.get('url');

Expand Down Expand Up @@ -31,3 +32,5 @@ export async function GET(request: NextRequest) {
return NextResponse.json({ error: 'Failed to fetch image' }, { status: 500 });
}
}

export const GET = withIPCheck(getHandler);
42 changes: 42 additions & 0 deletions apps/web/app/frames/proxy-ip-check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ipSafe } from 'apps/web/src/middleware/ipSafe';
import dns from 'dns/promises';
import ipaddr from 'ipaddr.js';
import { NextRequest, NextResponse } from 'next/server';
import { URL } from 'url';

export function withIPCheck(handler: (req: NextRequest) => Promise<Response>) {
return async function (req: NextRequest) {
const searchParams = req.nextUrl.searchParams;
const url = searchParams.get('url');

if (url) {
try {
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname;
const resolvedAddresses = await dns.resolve(hostname);

let allSafe = true;

for (const address of resolvedAddresses) {
if (ipaddr.isValid(address)) {
if (!ipSafe(address)) {
allSafe = false;
}
} else {
return NextResponse.json({ message: 'Invalid IP address resolution' }, { status: 400 });
}
}

if (!allSafe) {
return NextResponse.json({ message: 'Forbidden' }, { status: 403 });
}

return await handler(req);
} catch (error) {
return NextResponse.json({ message: 'Invalid URL format' }, { status: 400 });
}
}

return handler(req);
};
}
43 changes: 1 addition & 42 deletions apps/web/app/frames/route.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,5 @@
import { GET as getHandler, POST as postHandler } from '@frames.js/render/next';
import { ipSafe } from 'apps/web/src/middleware/ipSafe';
import { NextRequest, NextResponse } from 'next/server';
import ipaddr from 'ipaddr.js';
import { URL } from 'url';
import dns from 'dns/promises';

function withIPCheck(handler: (req: NextRequest) => Promise<Response>) {
return async function (req: NextRequest) {
const searchParams = req.nextUrl.searchParams;
const url = searchParams.get('url');

if (url) {
try {
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname;
const resolvedAddresses = await dns.resolve(hostname);

let allSafe = true;

for (const address of resolvedAddresses) {
if (ipaddr.isValid(address)) {
if (!ipSafe(address)) {
allSafe = false;
}
} else {
return NextResponse.json({ message: 'Invalid IP address resolution' }, { status: 400 });
}
}

if (!allSafe) {
return NextResponse.json({ message: 'Forbidden' }, { status: 403 });
}

return await handler(req);
} catch (error) {
return NextResponse.json({ message: 'Invalid URL format' }, { status: 400 });
}
}

return handler(req);
};
}
import { withIPCheck } from 'apps/web/app/frames/proxy-ip-check';

export const GET = withIPCheck(getHandler);
export const POST = withIPCheck(postHandler);

0 comments on commit 514acd1

Please sign in to comment.