proxy-addr
Determine the real client IP address behind trusted proxies, with full IPv4, IPv6, and CIDR support.
Repository Health
Technical Analysis
proxy-addr is a small, focused Node.js library that answers one question reliably: given a request that may have passed through one or more reverse proxies, what is the actual client IP address? It walks the X-Forwarded-For chain (via the forwarded package) from the socket address outward, stopping at the first address the caller does not trust, so applications never blindly accept a spoofed header value.
Trust is expressed as a function, a single IP/CIDR string, or an array of addresses and pre-defined named ranges (loopback, linklocal, uniquelocal), compiled once into an optimized matcher via proxyaddr.compile(). Because it underpins Express’s req.ip and trust proxy setting, it is one of the most widely depended-on packages in the Node.js HTTP ecosystem, downloaded well over 100 million times a week.
What You Get
- A single
proxyaddr(req, trust)function that returns the closest untrusted client address for a request proxyaddr.all(req, trust)to retrieve the full ordered address chain instead of just the final resultproxyaddr.compile(val)to pre-compile a trust specification into a fast, reusable trust function- Built-in named trust ranges (
loopback,linklocal,uniquelocal) covering common private/reserved address blocks - Native support for IPv4, IPv6, IPv4-mapped IPv6 normalization, and CIDR/netmask notation
Common Use Cases
- Implementing Express’s
trust proxysetting andreq.ipresolution behind Nginx, HAProxy, or a cloud load balancer - Safely resolving client IPs for rate limiting or abuse detection without trusting attacker-supplied
X-Forwarded-Forheaders - Geo-IP or analytics pipelines that need the true originating address behind a CDN or reverse-proxy chain
- Custom HTTP middleware or frameworks that need to whitelist specific internal proxy subnets as trusted hops
Under The Hood
Architecture
The module is a single dense file organized around one pipeline: compile() turns a trust specification (string, array, or named range like loopback) into resolved IP/CIDR subnets via parseipNotation(), which compileTrust() then turns into an optimized closure — trustNone, trustSingle, or trustMulti depending on how many subnets were given. alladdrs() retrieves the address chain from forwarded(req) and walks it front-to-back, truncating at the first address the compiled trust function rejects; proxyaddr() simply returns the last surviving entry. The design cleanly separates parsing (turning user input into subnets), compilation (turning subnets into a fast matcher), and evaluation (applying the matcher to a request), so the core abstraction — the trust function — is the only thing a caller depending on custom trust logic needs to reason about.
Tech Stack
Pure, dependency-light JavaScript (CommonJS, 'use strict', ES5-style var declarations for broad Node compatibility down to Node 0.10) with exactly two runtime dependencies: forwarded for X-Forwarded-For parsing and ipaddr.js for IP parsing, CIDR matching, and IPv4/IPv6 conversion. No build step is required — the package ships index.js directly. Tests run via Mocha with coverage through nyc, and linting uses ESLint with the standard config.
Code Quality
The test suite is extensive relative to the package’s size, covering argument validation, IPv4/IPv6/CIDR/netmask parsing edge cases, pre-defined range expansion, and both function- and array-based trust policies, run with --check-leaks and --bail for strict CI discipline. CI runs the full suite across a wide matrix of Node.js versions from 0.10 through current, plus CodeQL static analysis and an OpenSSF Scorecard workflow — unusually thorough security posture for a package this small. Comments follow a consistent JSDoc-style convention throughout, though there are no TypeScript types shipped natively (DefinitelyTyped covers that separately).
API Design
The public surface is deliberately minimal: one primary function plus two small helpers (all, compile), all exported from a single module with no configuration object or class to instantiate. The trust argument’s overloaded string/array/function acceptance covers the common cases (a hardcoded proxy IP, a CIDR range, a fully custom policy) without forcing callers into boilerplate, and pre-compiling a trust function via compile() up front is explicitly documented as the recommended pattern for per-request performance.
Used by 4 apps in this directory
Directus
CMS · Low Code Platforms
Connect any SQL database and get instant REST and GraphQL APIs, a visual management Studio, and a native MCP server for AI agents — free for most organizations.
FastGPT
AI Agents · AI Development
Build, debug, and deploy knowledge-based AI agents with a visual workflow editor, RAG retrieval, and support for any OpenAI-compatible LLM.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
PeerTube
Social Media
A federated, ActivityPub-based video hosting platform built by Framasoft — self-hostable instances interconnect into a network with no vendor lock-in, P2P-assisted streaming, and no ads.