From 7e13160bebfee06de8ce9c73c7934e81d6f81024 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Mon, 14 Sep 2026 22:36:37 +0000 Subject: [PATCH 1/2] remoteip: avoid pointer underflow on empty header token Signed-off-by: Robert McConnell --- modules/metadata/mod_remoteip.c | 8 ++++---- test/modules/proxy/test_03_response.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index 805c6543ea5..e017d9aec4f 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -616,12 +616,12 @@ static int remoteip_modify_request(request_rec *r) ++parse_remote; } - eos = parse_remote + strlen(parse_remote) - 1; - while (eos >= parse_remote && *eos == ' ') { - *(eos--) = '\0'; + eos = parse_remote + strlen(parse_remote); + while (eos > parse_remote && eos[-1] == ' ') { + *--eos = '\0'; } - if (eos < parse_remote) { + if (eos == parse_remote) { if (remote) { *(remote + strlen(remote)) = ','; } diff --git a/test/modules/proxy/test_03_response.py b/test/modules/proxy/test_03_response.py index 5c22528debd..4f21f43508c 100644 --- a/test/modules/proxy/test_03_response.py +++ b/test/modules/proxy/test_03_response.py @@ -80,6 +80,7 @@ def _class_scope(self, env): conf.add([ "RemoteIPHeader X-Forwarded-For", "RemoteIPTrustedProxy 0.0.0.0", + "RemoteIPTrustedProxy 127.0.0.1", ]) conf.end_vhost() conf.install() @@ -106,6 +107,16 @@ def test_proxy_03_004(self, env): assert "x-empty" in r.response["header"] assert r.response["body"] == b"Hello" + # a trailing empty RemoteIPHeader token must not underflow the trim pointer + def test_proxy_03_005(self, env): + if not env.has_shared_module("remoteip"): + pytest.skip("need mod_remoteip for this") + + r = env.curl_get(env.mkurl("http", "test1", "/forwarded"), options=[ + '-H', 'X-Forwarded-For: 192.0.2.1,', + ]) + assert r.response["status"] == 200 + # checks X-Forwarded headers def test_proxy_03_002(self, env): if not env.httpd_is_at_least("2.4.54"): From a9eb88f65d6369bfb2f0ac512ef9cf11832f92a2 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Wed, 16 Sep 2026 09:26:24 -0400 Subject: [PATCH 2/2] test: keep proxy response tests in numeric order --- test/modules/proxy/test_03_response.py | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/modules/proxy/test_03_response.py b/test/modules/proxy/test_03_response.py index 4f21f43508c..cce0d622357 100644 --- a/test/modules/proxy/test_03_response.py +++ b/test/modules/proxy/test_03_response.py @@ -100,23 +100,6 @@ def test_proxy_03_001(self, env): lognos=["AH01106", "AH10404"] ) - # empty backend response header values are valid - def test_proxy_03_004(self, env): - r = env.curl_get(env.mkurl("http", "test1", "/empty-header")) - assert r.response["status"] == 200 - assert "x-empty" in r.response["header"] - assert r.response["body"] == b"Hello" - - # a trailing empty RemoteIPHeader token must not underflow the trim pointer - def test_proxy_03_005(self, env): - if not env.has_shared_module("remoteip"): - pytest.skip("need mod_remoteip for this") - - r = env.curl_get(env.mkurl("http", "test1", "/forwarded"), options=[ - '-H', 'X-Forwarded-For: 192.0.2.1,', - ]) - assert r.response["status"] == 200 - # checks X-Forwarded headers def test_proxy_03_002(self, env): if not env.httpd_is_at_least("2.4.54"): @@ -150,3 +133,20 @@ def test_proxy_03_003(self, env): env.httpd_error_log.ignore_recent( lognos=["AH00957", "AH00959", "AH01114"] ) + + # empty backend response header values are valid + def test_proxy_03_004(self, env): + r = env.curl_get(env.mkurl("http", "test1", "/empty-header")) + assert r.response["status"] == 200 + assert "x-empty" in r.response["header"] + assert r.response["body"] == b"Hello" + + # a trailing empty RemoteIPHeader token must not underflow the trim pointer + def test_proxy_03_005(self, env): + if not env.has_shared_module("remoteip"): + pytest.skip("need mod_remoteip for this") + + r = env.curl_get(env.mkurl("http", "test1", "/forwarded"), options=[ + '-H', 'X-Forwarded-For: 192.0.2.1,', + ]) + assert r.response["status"] == 200