Skip to content

Commit 1bfd566

Browse files
committed
Add tests for CVE-2016-1000107 fix
1 parent 2324b79 commit 1bfd566

File tree

4 files changed

+110
-6
lines changed

4 files changed

+110
-6
lines changed

lib/inets/examples/server_root/cgi-bin/printenv.bat

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,33 @@
1+
::
2+
:: %CopyrightBegin%
3+
::
4+
:: SPDX-License-Identifier: Apache-2.0
5+
::
6+
:: Copyright Ericsson AB 1997-2025. All Rights Reserved.
7+
::
8+
:: Licensed under the Apache License, Version 2.0 (the "License");
9+
:: you may not use this file except in compliance with the License.
10+
:: You may obtain a copy of the License at
11+
::
12+
:: http://www.apache.org/licenses/LICENSE-2.0
13+
::
14+
:: Unless required by applicable law or agreed to in writing, software
15+
:: distributed under the License is distributed on an "AS IS" BASIS,
16+
:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
:: See the License for the specific language governing permissions and
18+
:: limitations under the License.
19+
::
20+
:: %CopyrightEnd%
21+
::
22+
::
23+
24+
125
@echo off
226
echo tomrad > c:\cygwin\tmp\hej
327
echo Content-type: text/html
428
echo.
529
echo ^<HTML^> ^<HEAD^> ^<TITLE^>OS Environment^</TITLE^> ^</HEAD^> ^<BODY^>^<PRE^>
30+
set http_proxy=%HTTP_PROXY%
631
set
732
echo ^</PRE^>^</BODY^>^</HTML^>
833

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
11
#!/bin/sh
2+
#
3+
# %CopyrightBegin%
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
#
7+
# Copyright Ericsson AB 1997-2025. All Rights Reserved.
8+
#
9+
# Licensed under the Apache License, Version 2.0 (the "License");
10+
# you may not use this file except in compliance with the License.
11+
# You may obtain a copy of the License at
12+
#
13+
# http://www.apache.org/licenses/LICENSE-2.0
14+
#
15+
# Unless required by applicable law or agreed to in writing, software
16+
# distributed under the License is distributed on an "AS IS" BASIS,
17+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
# See the License for the specific language governing permissions and
19+
# limitations under the License.
20+
#
21+
# %CopyrightEnd%
22+
#
23+
#
24+
25+
226
echo "Content-type: text/html"
327
echo ""
428
echo "<HTML> <HEAD> <TITLE>OS Environment</TITLE> </HEAD> <BODY><PRE>"
29+
export http_proxy=$HTTP_PROXY
530
env
6-
echo "</PRE></BODY></HTML>"
31+
echo "</PRE></BODY></HTML>"

lib/inets/src/http_server/httpd_script_env.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
%%
4242
%% Description: Creates a list of cgi/esi environment variables and
4343
%% there values.
44+
%%
45+
%% Note: "PROXY" header/variable is skipped because of CVE-2016-1000107
4446
%%--------------------------------------------------------------------------
4547
create_env(ScriptType, ModData, ScriptElements) ->
4648
create_basic_elements(ScriptType, ModData)
@@ -132,7 +134,7 @@ create_http_header_elements(ScriptType, [{Name, Value} | Headers], Acc, OtherAcc
132134
when is_list(Value) ->
133135
try http_env_element(ScriptType, Name, Value) of
134136
skipped ->
135-
create_http_header_elements(ScriptType, Headers, Acc, [OtherAcc]);
137+
create_http_header_elements(ScriptType, Headers, Acc, OtherAcc);
136138
Element ->
137139
create_http_header_elements(ScriptType, Headers, [Element | Acc],
138140
OtherAcc)

lib/inets/test/httpd_SUITE.erl

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
%% Seconds before successful auths timeout.
4343
-define(AUTH_TIMEOUT,5).
4444
-define(URL_START, "http://").
45-
45+
-define(URL_START_HTTPS, "https://").
46+
-define(SSL_NO_VERIFY, {ssl, [{verify, verify_none}]}).
4647
%%--------------------------------------------------------------------
4748
%% Common Test interface functions -----------------------------------
4849
%%--------------------------------------------------------------------
@@ -133,13 +134,14 @@ groups() ->
133134
{security, [], [security_1_1, security_1_0]},
134135
{logging, [], [disk_log_internal, disk_log_exists,
135136
disk_log_bad_size, disk_log_bad_file]},
136-
{http_1_1, [], [esi_propagate, esi_atom_leak, {group, http_1_1_parallel}] ++ load()},
137+
{http_1_1, [], [esi_propagate, esi_atom_leak, {group, http_1_1_parallel},
138+
cgi_bin_env] ++ load()},
137139
{http_1_1_parallel, [parallel],
138140
[host, chunked, expect, cgi, cgi_chunked_encoding_test,
139141
trace, range, if_modified_since, mod_esi_chunk_timeout,
140142
esi_put, esi_patch, esi_post, esi_headers]
141143
++ http_head() ++ http_get()},
142-
{http_1_0, [], [{group, http_1_0_parallel} | load()]},
144+
{http_1_0, [], [cgi_bin_env, {group, http_1_0_parallel} | load()]},
143145
{http_1_0_parallel, [parallel], [host, cgi, trace] ++ http_head() ++ http_get()},
144146
{http_rel_path_script_alias, [], [cgi]},
145147
{esi, [], [erl_script_timeout_default,
@@ -1291,6 +1293,51 @@ alias(Config) when is_list(Config) ->
12911293
[Test301(T) || T <- TestURIs301],
12921294
ok.
12931295

1296+
cgi_bin_env() ->
1297+
[{doc, "Test whether HTTP_PROXY header is not applied to an environment
1298+
that runs the cgi script"}].
1299+
cgi_bin_env(Config) ->
1300+
Proto = case proplists:get_value(type, Config, undefined) =:= ssl of
1301+
true -> https;
1302+
_ -> http
1303+
end,
1304+
Cgi = case os:type() of
1305+
{win32, _} ->
1306+
"printenv.bat";
1307+
_ ->
1308+
"printenv.sh"
1309+
end,
1310+
HttpOpts = case Proto of
1311+
https -> [?SSL_NO_VERIFY];
1312+
_ -> []
1313+
end,
1314+
RandomString = base64:encode(crypto:strong_rand_bytes(9)),
1315+
Endpoint = "/cgi-bin/" ++ Cgi,
1316+
Env = os:env(),
1317+
%% Grab the value of HTTP_PROXY from the environment before the request
1318+
HttpProxyEnv = proplists:get_value("HTTP_PROXY", Env, undefined),
1319+
Url = url(Proto, Endpoint, Config),
1320+
{ok, {_Status, _Headers, Body}} = httpc:request(get, {Url, [{"PROXY", RandomString},
1321+
{"proxy", RandomString}]},
1322+
HttpOpts, []),
1323+
%% The script prints the system's environment to the body so we need to
1324+
%% grab the value of interest
1325+
HttpEnv = re:split(Body, "\n"),
1326+
BinSize = size(<<"HTTP_PROXY">>) * 8,
1327+
%% Filter keys of interest, while converting to proplist
1328+
EnvProp = [{binary_to_list(Key), binary_to_list(Val)} ||
1329+
<<Key:BinSize/bitstring, "=", Val/bitstring>> <- HttpEnv,
1330+
Key =:= <<"HTTP_PROXY">>],
1331+
%% EnvProp should only have HTTP_PROXY or be an empty list
1332+
RespHttpProxyEnv = proplists:get_value("HTTP_PROXY", EnvProp, undefined),
1333+
case HttpProxyEnv of
1334+
undefined ->
1335+
%% HTTP_PROXY was not set before the request
1336+
?assertEqual([], EnvProp);
1337+
_ ->
1338+
%% HTTP_PROXY was set, so ensure it's the same in the body
1339+
?assertEqual(HttpProxyEnv, RespHttpProxyEnv)
1340+
end.
12941341
%%-------------------------------------------------------------------------
12951342
actions() ->
12961343
[{doc, "Test mod_actions"}].
@@ -1983,10 +2030,15 @@ tls_alert(Config) when is_list(Config) ->
19832030
%%--------------------------------------------------------------------
19842031
%% Internal functions -----------------------------------
19852032
%%--------------------------------------------------------------------
2033+
url(https, End, Config) ->
2034+
?URL_START_HTTPS ++ url(End, Config);
19862035
url(http, End, Config) ->
2036+
?URL_START ++ url(End, Config).
2037+
2038+
url(End, Config) ->
19872039
Port = proplists:get_value(port, Config),
19882040
{ok,Host} = inet:gethostname(),
1989-
?URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End.
2041+
Host ++ ":" ++ integer_to_list(Port) ++ End.
19902042

19912043
http_get_url(Port0, HeaderDelay, ChunkDelay, BadChunkDelay) ->
19922044
{ok, Host} = inet:gethostname(),

0 commit comments

Comments
 (0)