Skip to content

Commit f176717

Browse files
committed
fix: improve client IP extraction logic in headers
1 parent 6fada07 commit f176717

2 files changed

Lines changed: 8 additions & 6 deletions

File tree

‎adminforth/auth.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ class AdminForthAuth implements IAdminForthAuth {
7070
if (clientIpHeader) {
7171
ip = headersLower[clientIpHeader.toLowerCase()];
7272
} else {
73-
// first try common headers which can't bee spoofed, in other words
74-
// most common to nginx/traefik/apache
73+
// proxies append the client address to the end of X-Forwarded-For,
74+
// everything before it is sent by the client and can be spoofed
7575
// then fallback to less secure headers
76-
ip = headersLower['x-forwarded-for']?.split(',').shift().trim() ||
76+
ip = headersLower['x-forwarded-for']?.split(',').pop().trim() ||
7777
headersLower['x-real-ip'] ||
7878
headersLower['x-client-ip'] ||
7979
headersLower['x-cluster-client-ip'] ||

‎documentation/docs/tutorial/03-Customization/12-security.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ This function is used for:
165165
- Securely logging user actions e.g. in Audit Log plugin
166166
- Can be used by your own code e.g. hooks to write first login/last login IP address to db
167167
168-
By default it reads `X-Forwarded-For` header from request headers to determine client IP address.
169-
AdminForth does not understand whether this header can be trusted or no. In some cases it might be spoofed by client like this:
168+
By default it takes the last IP address from `X-Forwarded-For` header. Proxies append the address of their client to the end of this header and keep everything the client sent before it, so the last address is the one added by your nearest proxy.
169+
AdminForth does not understand whether this header can be trusted or no. If there is no proxy in front of the app, the whole header comes from the client and might be spoofed like this:
170170
171171
```
172172
curl -H "X-Forwarded-For: <made-out IP>" http://your-server/api...
@@ -198,7 +198,9 @@ new AdminForth({
198198
### Using reverse proxy
199199
200200
If first client-facing point is reverse proxy like Nginx or Traefik and there is no more proxies like CDN behind it, you should take care of reliably setting `X-Forwarded-For` header to the client IP address.
201-
Main trick here is to make sure that proxy strips any `X-Forwarded-For` headers that are already present in the requeqst and hardly overwrites it with client IP address coming from TCP connection (so it can't be spoofed by client).
201+
Proxy should either append client IP address coming from TCP connection to the end of the header (nginx `$proxy_add_x_forwarded_for`), or strip any `X-Forwarded-For` headers that are already present in the request and overwrite it with this address (so it can't be spoofed by client).
202+
203+
If there are several proxies in a chain (e.g. Cloudflare in front of nginx), the last address in `X-Forwarded-For` belongs to the previous proxy, not to the client, so use `auth.clientIpHeader` as described above.
202204
203205
204206
In Traefik to set `X-Forwarded-For` header you should set `forwardedHeaders` in traefik config:

0 commit comments

Comments
 (0)