Skip to content

Commit

Permalink
Exempt SCRIPT_NAME from newly introduced --header-map treatment
Browse files Browse the repository at this point in the history
  • Loading branch information
pajod committed Apr 24, 2024
1 parent 5b68c17 commit 8d93ff8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
12 changes: 8 additions & 4 deletions gunicorn/config.py
Expand Up @@ -1261,17 +1261,18 @@ class ForwardedAllowIPS(Setting):
cli = ["--forwarded-allow-ips"]
meta = "STRING"
validator = validate_string_to_list
default = os.environ.get("FORWARDED_ALLOW_IPS", "127.0.0.1")
default = os.environ.get("FORWARDED_ALLOW_IPS", "127.0.0.1,::1")
desc = """\
Front-end's IPs from which allowed to handle set secure headers.
(comma separate).
Set to ``*`` to disable checking of Front-end IPs (useful for setups
Set to ``*`` to disable checking of Front-end IPs. This is useful for setups
where you don't know in advance the IP address of Front-end, but
you still trust the environment).
instead have ensured via other means that none other than your
authorized Front-ends can access gunicorn.
By default, the value of the ``FORWARDED_ALLOW_IPS`` environment
variable. If it is not defined, the default is ``"127.0.0.1"``.
variable. If it is not defined, the default is ``"127.0.0.1,::1"``.
.. note::
Expand Down Expand Up @@ -2358,6 +2359,9 @@ class HeaderMap(Setting):
The value ``dangerous`` matches the previous, not advisabble, behaviour of mapping different
header field names into the same environ name.
The (at this time, not configurable) header `SCRIPT_NAME` is permitted
without consulting this setting, if it is received from an allowed forwarder.
Use with care and only if necessary and after considering if your problem could
instead be solved by specifically renaming or rewriting only the intended headers
on a proxy in front of Gunicorn.
Expand Down
7 changes: 6 additions & 1 deletion gunicorn/http/message.py
Expand Up @@ -77,6 +77,7 @@ def parse_headers(self, data, from_trailer=False):
# handle scheme headers
scheme_header = False
secure_scheme_headers = {}
allowed_forwarder_headers = []
if from_trailer:
# nonsense. either a request is https from the beginning
# .. or we are just behind a proxy who does not remove conflicting trailers
Expand All @@ -85,6 +86,7 @@ def parse_headers(self, data, from_trailer=False):
not isinstance(self.peer_addr, tuple)
or self.peer_addr[0] in cfg.forwarded_allow_ips):
secure_scheme_headers = cfg.secure_scheme_headers
allowed_forwarder_headers = ["SCRIPT_NAME"]

# Parse headers into key/value pairs paying attention
# to continuation lines.
Expand Down Expand Up @@ -140,7 +142,10 @@ def parse_headers(self, data, from_trailer=False):
# HTTP_X_FORWARDED_FOR = 2001:db8::ha:cc:ed,127.0.0.1,::1
# Only modify after fixing *ALL* header transformations; network to wsgi env
if "_" in name:
if self.cfg.header_map == "dangerous":
if name in allowed_forwarder_headers:
# This forwarder may override our environment
pass
elif self.cfg.header_map == "dangerous":
# as if we did not know we cannot safely map this
pass
elif self.cfg.header_map == "drop":
Expand Down

0 comments on commit 8d93ff8

Please sign in to comment.