File 0990-Add-tests-for-CVE-2016-1000107-fix.patch of Package erlang
From 1bfd5669c0d77c8478b23ecf89e9a25da449b38e Mon Sep 17 00:00:00 2001
From: Konrad Pietrzak <konrad@erlang.org>
Date: Tue, 12 Aug 2025 16:06:23 +0200
Subject: [PATCH 3/3] Add tests for CVE-2016-1000107 fix
---
.../examples/server_root/cgi-bin/printenv.bat | 25 ++++++++
.../examples/server_root/cgi-bin/printenv.sh | 27 ++++++++-
.../src/http_server/httpd_script_env.erl | 4 +-
lib/inets/test/httpd_SUITE.erl | 60 +++++++++++++++++--
4 files changed, 110 insertions(+), 6 deletions(-)
diff --git a/lib/inets/examples/server_root/cgi-bin/printenv.bat b/lib/inets/examples/server_root/cgi-bin/printenv.bat
index 25a49a1536..be2bb83070 100644
--- a/lib/inets/examples/server_root/cgi-bin/printenv.bat
+++ b/lib/inets/examples/server_root/cgi-bin/printenv.bat
@@ -1,8 +1,33 @@
+::
+:: %CopyrightBegin%
+::
+:: SPDX-License-Identifier: Apache-2.0
+::
+:: Copyright Ericsson AB 1997-2025. All Rights Reserved.
+::
+:: Licensed under the Apache License, Version 2.0 (the "License");
+:: you may not use this file except in compliance with the License.
+:: You may obtain a copy of the License at
+::
+:: http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing, software
+:: distributed under the License is distributed on an "AS IS" BASIS,
+:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+:: See the License for the specific language governing permissions and
+:: limitations under the License.
+::
+:: %CopyrightEnd%
+::
+::
+
+
@echo off
echo tomrad > c:\cygwin\tmp\hej
echo Content-type: text/html
echo.
echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^>
+set http_proxy=%HTTP_PROXY%
set
echo ^</PRE^>^</BODY^>^</HTML^>
diff --git a/lib/inets/examples/server_root/cgi-bin/printenv.sh b/lib/inets/examples/server_root/cgi-bin/printenv.sh
index de81de9bde..c5e0f06a37 100755
--- a/lib/inets/examples/server_root/cgi-bin/printenv.sh
+++ b/lib/inets/examples/server_root/cgi-bin/printenv.sh
@@ -1,6 +1,31 @@
#!/bin/sh
+#
+# %CopyrightBegin%
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Copyright Ericsson AB 1997-2025. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# %CopyrightEnd%
+#
+#
+
+
echo "Content-type: text/html"
echo ""
echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>"
+export http_proxy=$HTTP_PROXY
env
-echo "</PRE></BODY></HTML>"
\ No newline at end of file
+echo "</PRE></BODY></HTML>"
diff --git a/lib/inets/src/http_server/httpd_script_env.erl b/lib/inets/src/http_server/httpd_script_env.erl
index 0e6857dbf8..c254f70bf8 100644
--- a/lib/inets/src/http_server/httpd_script_env.erl
+++ b/lib/inets/src/http_server/httpd_script_env.erl
@@ -41,6 +41,8 @@
%%
%% Description: Creates a list of cgi/esi environment variables and
%% there values.
+%%
+%% Note: "PROXY" header/variable is skipped because of CVE-2016-1000107
%%--------------------------------------------------------------------------
create_env(ScriptType, ModData, ScriptElements) ->
create_basic_elements(ScriptType, ModData)
@@ -132,7 +134,7 @@ create_http_header_elements(ScriptType, [{Name, Value} | Headers], Acc, OtherAcc
when is_list(Value) ->
try http_env_element(ScriptType, Name, Value) of
skipped ->
- create_http_header_elements(ScriptType, Headers, Acc, [OtherAcc]);
+ create_http_header_elements(ScriptType, Headers, Acc, OtherAcc);
Element ->
create_http_header_elements(ScriptType, Headers, [Element | Acc],
OtherAcc)
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 9ac2e07bb5..b399713827 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -42,7 +42,8 @@
%% Seconds before successful auths timeout.
-define(AUTH_TIMEOUT,5).
-define(URL_START, "http://").
-
+-define(URL_START_HTTPS, "https://").
+-define(SSL_NO_VERIFY, {ssl, [{verify, verify_none}]}).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
@@ -139,9 +139,9 @@ groups() ->
{http_1_1, [],
[host, chunked, expect, cgi, cgi_chunked_encoding_test,
trace, range, if_modified_since, mod_esi_chunk_timeout,
- esi_put, esi_patch, esi_post, esi_proagate, esi_atom_leak, esi_headers]
+ esi_put, esi_patch, esi_post, esi_proagate, esi_atom_leak, esi_headers, cgi_bin_env]
++ http_head() ++ http_get() ++ load()},
- {http_1_0, [], [host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
+ {http_1_0, [], [cgi_bin_env, host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
{http_rel_path_script_alias, [], [cgi]},
{not_sup, [], [put_not_sup]}
].
@@ -1291,6 +1293,51 @@ alias(Config) when is_list(Config) ->
[Test301(T) || T <- TestURIs301],
ok.
+cgi_bin_env() ->
+[{doc, "Test whether HTTP_PROXY header is not applied to an environment
+that runs the cgi script"}].
+cgi_bin_env(Config) ->
+ Proto = case proplists:get_value(type, Config, undefined) =:= ssl of
+ true -> https;
+ _ -> http
+ end,
+ Cgi = case os:type() of
+ {win32, _} ->
+ "printenv.bat";
+ _ ->
+ "printenv.sh"
+ end,
+ HttpOpts = case Proto of
+ https -> [?SSL_NO_VERIFY];
+ _ -> []
+ end,
+ RandomString = base64:encode(crypto:strong_rand_bytes(9)),
+ Endpoint = "/cgi-bin/" ++ Cgi,
+ Env = os:env(),
+ %% Grab the value of HTTP_PROXY from the environment before the request
+ HttpProxyEnv = proplists:get_value("HTTP_PROXY", Env, undefined),
+ Url = url(Proto, Endpoint, Config),
+ {ok, {_Status, _Headers, Body}} = httpc:request(get, {Url, [{"PROXY", RandomString},
+ {"proxy", RandomString}]},
+ HttpOpts, []),
+ %% The script prints the system's environment to the body so we need to
+ %% grab the value of interest
+ HttpEnv = re:split(Body, "\n"),
+ BinSize = size(<<"HTTP_PROXY">>) * 8,
+ %% Filter keys of interest, while converting to proplist
+ EnvProp = [{binary_to_list(Key), binary_to_list(Val)} ||
+ <<Key:BinSize/bitstring, "=", Val/bitstring>> <- HttpEnv,
+ Key =:= <<"HTTP_PROXY">>],
+ %% EnvProp should only have HTTP_PROXY or be an empty list
+ RespHttpProxyEnv = proplists:get_value("HTTP_PROXY", EnvProp, undefined),
+ case HttpProxyEnv of
+ undefined ->
+ %% HTTP_PROXY was not set before the request
+ ?assertEqual([], EnvProp);
+ _ ->
+ %% HTTP_PROXY was set, so ensure it's the same in the body
+ ?assertEqual(HttpProxyEnv, RespHttpProxyEnv)
+ end.
%%-------------------------------------------------------------------------
actions() ->
[{doc, "Test mod_actions"}].
@@ -1983,10 +2030,15 @@ tls_alert(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
%% Internal functions -----------------------------------
%%--------------------------------------------------------------------
+url(https, End, Config) ->
+ ?URL_START_HTTPS ++ url(End, Config);
url(http, End, Config) ->
+ ?URL_START ++ url(End, Config).
+
+url(End, Config) ->
Port = proplists:get_value(port, Config),
{ok,Host} = inet:gethostname(),
- ?URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End.
+ Host ++ ":" ++ integer_to_list(Port) ++ End.
http_get_url(Port0, HeaderDelay, ChunkDelay, BadChunkDelay) ->
{ok, Host} = inet:gethostname(),
--
2.43.0