mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 20:32:25 +03:00
fix(security): sanitize agent-card topology, anti-spoof login rate-limit peer IP, and add 429 Retry-After (#S1 #S2 #S4) (#11418)
Validado em lote combinado (batch-0824g) contra o tip de release/v3.8.50: typecheck:core limpo, gates estáticos OK, 62/62 testes focados passando (S1/S2/S4, tests/unit/security-s1-s2-s4.test.ts, 9/9). Boa integração com o padrão já existente de peer IP stamped por HMAC (resolveStampedPeer/OMNIROUTE_PEER_STAMP_TOKEN) — reusa em vez de reimplementar, e o header confiável só é honrado quando o stamp token está configurado. S2 remove corretamente a disclosure de topologia hardcoded do agent-card. Obrigado pela contribuição!
This commit is contained in:
@@ -62,6 +62,16 @@ export const VIA_PROXY_HEADER = "x-omniroute-via-proxy";
|
||||
*/
|
||||
export const AUTHZ_HEADER_PEER_LOCALITY = "x-omniroute-peer-locality";
|
||||
|
||||
/**
|
||||
* The resolved real peer IP, stamped by the pipeline AFTER verifying the
|
||||
* token-stamped PEER_IP_HEADER. This is the trusted, non-spoofable IP that
|
||||
* route handlers (e.g. login rate-limit key) should use instead of re-deriving
|
||||
* from X-Forwarded-For / X-Real-IP. Set only when the stamp token is configured
|
||||
* and the HMAC signature validates; absent when the stamp is not in use.
|
||||
* Stripped from incoming requests like all other trusted headers.
|
||||
*/
|
||||
export const AUTHZ_HEADER_TRUSTED_PEER_IP = "x-omniroute-trusted-peer-ip";
|
||||
|
||||
/**
|
||||
* Headers the pipeline must NEVER trust on incoming requests. They are
|
||||
* stripped before route classification to prevent header-spoofing attacks.
|
||||
@@ -73,4 +83,5 @@ export const AUTHZ_TRUSTED_HEADERS: ReadonlyArray<string> = [
|
||||
AUTHZ_HEADER_AUTH_LABEL,
|
||||
AUTHZ_HEADER_AUTH_SCOPES,
|
||||
AUTHZ_HEADER_PEER_LOCALITY,
|
||||
AUTHZ_HEADER_TRUSTED_PEER_IP,
|
||||
];
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
AUTHZ_HEADER_PEER_LOCALITY,
|
||||
AUTHZ_HEADER_REQUEST_ID,
|
||||
AUTHZ_HEADER_ROUTE_CLASS,
|
||||
AUTHZ_HEADER_TRUSTED_PEER_IP,
|
||||
AUTHZ_TRUSTED_HEADERS,
|
||||
CLI_TOKEN_HEADER,
|
||||
PEER_IP_HEADER,
|
||||
@@ -332,6 +333,16 @@ export async function runAuthzPipeline(
|
||||
process.env.OMNIROUTE_PEER_STAMP_TOKEN
|
||||
);
|
||||
requestHeaders.set(AUTHZ_HEADER_PEER_LOCALITY, peerLocality);
|
||||
// Stamp the resolved, non-spoofable peer IP for route handlers that need
|
||||
// the real client IP (e.g. login rate-limit key). Only set when the stamp
|
||||
// token is configured and the HMAC signature validates; absent otherwise.
|
||||
const trustedPeerIp = resolveStampedPeer(
|
||||
request.headers.get(PEER_IP_HEADER),
|
||||
process.env.OMNIROUTE_PEER_STAMP_TOKEN
|
||||
);
|
||||
if (trustedPeerIp) {
|
||||
requestHeaders.set(AUTHZ_HEADER_TRUSTED_PEER_IP, trustedPeerIp);
|
||||
}
|
||||
// Local CLI-token auth is decided centrally above. Preserve that trusted
|
||||
// decision for route-level requireManagementAuth without forwarding the
|
||||
// machine token itself: custom client auth headers are stripped before the
|
||||
|
||||
Reference in New Issue
Block a user