# HG changeset patch # User Mads Kiilerich # Date 2021-05-09 20:32:51 # Node ID f08fbf4248986347690cd463913dba141276c4b8 # Parent 883a0c6c425f0f1124503554ecc6a430602de3ab auth: don't trust clients too much - only trust the *last* IP in the X-Forwarded-For header The X-Forwarded-For header contains a list of IP addresses, where each proxy server appends the IP they see their request coming from. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For . Trusting the *first* IP in HTTP_X_FORWARDED_FOR would allow clients to claim any IP, which could be used to bypass IP restrictions configured in Kallithea. Instead, only trust the last proxy in the chain, and thus only use the *last* IP in HTTP_X_FORWARDED_FOR. (In setups where more than last IP should be trusted, the last proxy server in the chain must be configured rewrite the header accordingly.) diff --git a/kallithea/controllers/base.py b/kallithea/controllers/base.py --- a/kallithea/controllers/base.py +++ b/kallithea/controllers/base.py @@ -64,15 +64,17 @@ def render(template_path): def _filter_proxy(ip): """ - HEADERS can have multiple ips inside the left-most being the original - client, and each successive proxy that passed the request adding the IP - address where it received the request from. + HTTP_X_FORWARDED_FOR headers can have multiple IP addresses, with the + leftmost being the original client. Each proxy that is forwarding the + request will usually add the IP address it sees the request coming from. - :param ip: + The client might have provided a fake leftmost value before hitting the + first proxy, so if we have a proxy that is adding one IP address, we can + only trust the rightmost address. """ if ',' in ip: _ips = ip.split(',') - _first_ip = _ips[0].strip() + _first_ip = _ips[-1].strip() log.debug('Got multiple IPs %s, using %s', ','.join(_ips), _first_ip) return _first_ip return ip