changeset 8885:f08fbf424898

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.)
author Mads Kiilerich <mads@kiilerich.com>
date Sun, 09 May 2021 22:32:51 +0200
parents 883a0c6c425f
children 3d7ba590f6f5
files kallithea/controllers/base.py
diffstat 1 files changed, 7 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/controllers/base.py	Sun May 09 22:17:21 2021 +0200
+++ b/kallithea/controllers/base.py	Sun May 09 22:32:51 2021 +0200
@@ -64,15 +64,17 @@
 
 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