mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-20 22:01:45 +00:00
Re-check SSRF on every redirect hop when resolving short links
Replace the one-shot checkSsrf + fetch(redirect:'follow') in the maps and place short-link resolvers with safeFetchFollow, which follows redirects manually and re-runs checkSsrf against the DNS-pinned IP of each hop (max 5). A redirect to an internal/loopback address is now blocked even when the initial URL is public, while legitimate cross-host redirects (goo.gl -> maps.google.com) still resolve.
This commit is contained in:
@@ -29,9 +29,26 @@ vi.mock('../../../src/db/database', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../../src/utils/ssrfGuard', () => ({
|
||||
checkSsrf: mockCheckSsrf,
|
||||
}));
|
||||
vi.mock('../../../src/utils/ssrfGuard', () => {
|
||||
class SsrfBlockedError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'SsrfBlockedError';
|
||||
}
|
||||
}
|
||||
return {
|
||||
checkSsrf: mockCheckSsrf,
|
||||
SsrfBlockedError,
|
||||
// Mirror the real per-hop helper closely enough for unit tests: run the
|
||||
// (mocked) SSRF check, then fetch through the (stubbed) global fetch. The
|
||||
// fetch stubs in these tests already return the final resolved response.
|
||||
safeFetchFollow: vi.fn(async (url: string, init?: any) => {
|
||||
const ssrf = await mockCheckSsrf(url);
|
||||
if (!ssrf.allowed) throw new SsrfBlockedError(ssrf.error ?? 'Request blocked by SSRF guard');
|
||||
return (globalThis.fetch as any)(url, init);
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../../../src/services/apiKeyCrypto', () => ({
|
||||
decrypt_api_key: (v: string | null) => v,
|
||||
|
||||
Reference in New Issue
Block a user