fix(api): resolve client ip from peer when untrusted (#3420)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-12 15:34:36 +02:00
1 parent 17746fcdc4
commit 68cb2a4bbb
13 files changed
+208 -54

No files matched your search

+6 -14
View File
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {ParsedIpAddress} from '@fluxer/ip_utils/src/IpAddress';
import {parseIpAddress} from '@fluxer/ip_utils/src/IpAddress';
import {canonicalizeIpAddress} from '@fluxer/ip_utils/src/IpAddress';
interface ClientIpExtractionOptions {
trustClientIpHeader?: boolean;
clientIpHeaderName?: string;
peerAddress?: string | null;
}
export class MissingClientIpError extends Error {
@@ -13,7 +13,7 @@ export class MissingClientIpError extends Error {
readonly status = 403;
constructor() {
super('Client IP header is required');
super('Client IP is required');
this.name = 'MissingClientIpError';
}
}
@@ -28,20 +28,12 @@ export function resolveClientIpHeaderName(clientIpHeaderName?: string): string {
return normalizeHeaderName(clientIpHeaderName ?? DEFAULT_CLIENT_IP_HEADER_NAME);
}
function parseClientIpHeaderValue(value: string | null): ParsedIpAddress | null {
if (value === null) {
return null;
}
return parseIpAddress(value.split(',', 1)[0]);
}
export function extractClientIp(req: Request, options?: ClientIpExtractionOptions): string | null {
if (!options?.trustClientIpHeader) {
return null;
return options?.peerAddress ? canonicalizeIpAddress(options.peerAddress) : null;
}
return (
parseClientIpHeaderValue(req.headers.get(resolveClientIpHeaderName(options.clientIpHeaderName)))?.normalized ?? null
);
const headerValue = req.headers.get(resolveClientIpHeaderName(options.clientIpHeaderName));
return headerValue === null ? null : canonicalizeIpAddress(headerValue.split(',', 1)[0]);
}
export function requireClientIp(req: Request, options?: ClientIpExtractionOptions): string {