From 4cdc756791cac61d9b7023bd94f1c87b47555598 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Tue, 22 Nov 2022 10:44:59 +0300 Subject: [PATCH] FIX: Parsing client IPv6 address when a proxy is involved (#457) --- CHANGELOG.md | 4 ++++ auditlog/middleware.py | 19 +++++++++++++------ auditlog_tests/tests.py | 5 +++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e76497..8a4880b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ # Changes +## Next Release + #### Fixes + - fix: Make log entries read-only in the admin. ([#449](https://github.com/jazzband/django-auditlog/pull/449)) +- fix: Handle IPv6 addresses in `X-Forwarded-For`. ([#457](https://github.com/jazzband/django-auditlog/pull/457)) ## 2.2.0 (2022-10-07) diff --git a/auditlog/middleware.py b/auditlog/middleware.py index 19875c9..00745bc 100644 --- a/auditlog/middleware.py +++ b/auditlog/middleware.py @@ -14,14 +14,21 @@ class AuditlogMiddleware: @staticmethod def _get_remote_addr(request): - if request.headers.get("X-Forwarded-For"): - # In case of proxy, set 'original' address - remote_addr = request.headers.get("X-Forwarded-For").split(",")[0] - # Remove port number from remote_addr - return remote_addr.split(":")[0] - else: + # In case there is no proxy, return the original address + if not request.headers.get("X-Forwarded-For"): return request.META.get("REMOTE_ADDR") + # In case of proxy, set 'original' address + remote_addr: str = request.headers.get("X-Forwarded-For").split(",")[0] + + # Remove port number from remote_addr + if "." in remote_addr and ":" in remote_addr: # IPv4 with port (`x.x.x.x:x`) + remote_addr = remote_addr.split(":")[0] + elif "[" in remote_addr: # IPv6 with port (`[:::]:x`) + remote_addr = remote_addr[1:].split("]")[0] + + return remote_addr + def __call__(self, request): remote_addr = self._get_remote_addr(request) diff --git a/auditlog_tests/tests.py b/auditlog_tests/tests.py index 52e7a8b..e88c706 100644 --- a/auditlog_tests/tests.py +++ b/auditlog_tests/tests.py @@ -450,6 +450,11 @@ class MiddlewareTest(TestCase): ({}, "127.0.0.1"), ({"HTTP_X_FORWARDED_FOR": "127.0.0.2"}, "127.0.0.2"), ({"HTTP_X_FORWARDED_FOR": "127.0.0.3:1234"}, "127.0.0.3"), + ({"HTTP_X_FORWARDED_FOR": "2606:4700:4700::1111"}, "2606:4700:4700::1111"), + ( + {"HTTP_X_FORWARDED_FOR": "[2606:4700:4700::1001]:1234"}, + "2606:4700:4700::1001", + ), ] for headers, expected_remote_addr in tests: with self.subTest(headers=headers):