From 2f14fa1805c8a69b2803ba6ffa066aa265ee6778 Mon Sep 17 00:00:00 2001
From: Kazuhiko SHIOZAKI <kazuhiko@nexedi.com>
Date: Fri, 26 Jun 2020 15:18:13 +0200
Subject: [PATCH] fixup! ERP5Type/patches: use the first entry of
 HTTP_X_FORWARDED_FOR as the source IP address.

---
 product/ERP5/bin/zopewsgi.py         |  5 +++--
 product/ERP5Type/ZopePatch.py        |  1 +
 product/ERP5Type/patches/WSGITask.py | 24 ++++++++++++++++++++++++
 3 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 product/ERP5Type/patches/WSGITask.py

diff --git a/product/ERP5/bin/zopewsgi.py b/product/ERP5/bin/zopewsgi.py
index b65692fbc6..ce52d1205b 100644
--- a/product/ERP5/bin/zopewsgi.py
+++ b/product/ERP5/bin/zopewsgi.py
@@ -138,8 +138,9 @@ def createServer(application, logger, **kw):
     global server
     server = create_server(
         TransLogger(application, logger=logger),
-        trusted_proxy='*',
-        trusted_proxy_headers=('x-forwarded-for',),
+        # We handle X-Forwarded-For by ourselves. See ERP5Type/patches/WSGITask.py.
+        # trusted_proxy='*',
+        # trusted_proxy_headers=('x-forwarded-for',),
         clear_untrusted_proxy_headers=True,
         **kw
     )
diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py
index e939461dd5..86f9e9ba4c 100644
--- a/product/ERP5Type/ZopePatch.py
+++ b/product/ERP5Type/ZopePatch.py
@@ -90,6 +90,7 @@ from Products.ERP5Type.patches import ZSQLMethod
 from Products.ERP5Type.patches import MimetypesRegistry
 from Products.ERP5Type.patches import users
 from Products.ERP5Type.patches import Publish
+from Products.ERP5Type.patches import WSGITask
 
 # These symbols are required for backward compatibility
 from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager
diff --git a/product/ERP5Type/patches/WSGITask.py b/product/ERP5Type/patches/WSGITask.py
new file mode 100644
index 0000000000..20a9344b51
--- /dev/null
+++ b/product/ERP5Type/patches/WSGITask.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+import ZPublisher.HTTPRequest
+from waitress.task import WSGITask
+
+WSGITask_get_environment = WSGITask.get_environment
+
+def get_environment(self):
+  if ZPublisher.HTTPRequest.trusted_proxies == ('0.0.0.0',): # Magic value to enable this functionality
+    # Frontend-facing proxy is responsible for sanitising
+    # X_FORWARDED_FOR, and only trusted accesses should bypass
+    # that proxy. So trust first entry.
+    forwarded_for = dict(self.request.headers).get('X_FORWARDED_FOR', '').split(',', 1)[0].strip()
+  else:
+    forwarded_for = None
+
+  environ = WSGITask_get_environment(self)
+
+  if forwarded_for:
+    environ['REMOTE_HOST'] = environ['REMOTE_ADDR'] = forwarded_for
+
+  return environ
+
+WSGITask.get_environment = get_environment
-- 
2.30.9