Skip to content

Commit

Permalink
fix the correct remote address
Browse files Browse the repository at this point in the history
The remote address should return the direct client addr not a forwarded
header.

This is a breaking change. The main problem with such changes is the way
the application or framework will handle the URL completion. Indeed most
of them are only expecting a TCP socket.

fix #633
  • Loading branch information
benoitc committed Dec 27, 2013
1 parent 776f315 commit c487368
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 52 deletions.
15 changes: 1 addition & 14 deletions gunicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -914,19 +914,6 @@ class SecureSchemeHeader(Setting):
"""


class XForwardedFor(Setting):
name = "x_forwarded_for_header"
section = "Server Mechanics"
cli = ["--x-forwarded-for-hdr"]
meta = "STRING"
validator = validate_string
default = 'X-FORWARDED-FOR'
desc = """\
Set the X-Forwarded-For header that identify the originating IP
address of the client connection to gunicorn via a proxy.
"""


class ForwardedAllowIPS(Setting):
name = "forwarded_allow_ips"
section = "Server Mechanics"
Expand All @@ -935,7 +922,7 @@ class ForwardedAllowIPS(Setting):
validator = validate_string_to_list
default = "127.0.0.1"
desc = """\
Front-end's IPs from which allowed to handle X-Forwarded-* headers.
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
Expand Down
51 changes: 13 additions & 38 deletions gunicorn/http/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,29 +80,22 @@ def create(req, sock, client, server, cfg):

environ = default_environ(req, sock, cfg)

# authors should be aware that REMOTE_HOST and REMOTE_ADDR
# may not qualify the remote addr:
# http://www.ietf.org/rfc/rfc3875
forward = client or "127.0.0.1"
url_scheme = "https" if cfg.is_ssl else "http"
script_name = os.environ.get("SCRIPT_NAME", "")

secure_headers = cfg.secure_scheme_headers
x_forwarded_for_header = cfg.x_forwarded_for_header
if '*' not in cfg.forwarded_allow_ips and client\
and client[0] not in cfg.forwarded_allow_ips:
x_forwarded_for_header = None
secure_headers = {}
if client and not isinstance(client, string_types):
if ('*' not in cfg.forwarded_allow_ips
and client[0] not in cfg.forwarded_allow_ips):
secure_headers = {}

for hdr_name, hdr_value in req.headers:
if hdr_name == "EXPECT":
# handle expect
if hdr_value.lower() == "100-continue":
sock.send(b"HTTP/1.1 100 Continue\r\n\r\n")
elif x_forwarded_for_header and hdr_name == x_forwarded_for_header:
forward = hdr_value
elif secure_headers and (hdr_name.upper() in secure_headers and
hdr_value == secure_headers[hdr_name.upper()]):
elif secure_headers and (hdr_name in secure_headers and
hdr_value == secure_headers[hdr_name]):
url_scheme = "https"
elif hdr_name == "HOST":
server = hdr_value
Expand All @@ -122,32 +115,14 @@ def create(req, sock, client, server, cfg):

environ['wsgi.url_scheme'] = url_scheme

if isinstance(forward, string_types):
# we only took the last one
# http://en.wikipedia.org/wiki/X-Forwarded-For
if forward.find(",") >= 0:
forward = forward.rsplit(",", 1)[1].strip()

# find host and port on ipv6 address
if '[' in forward and ']' in forward:
host = forward.split(']')[0][1:].lower()
elif ":" in forward and forward.count(":") == 1:
host = forward.split(":")[0].lower()
else:
host = forward

forward = forward.split(']')[-1]
if ":" in forward and forward.count(":") == 1:
port = forward.split(':', 1)[1]
else:
port = 80

remote = (host, port)
# authors should be aware that REMOTE_HOST and REMOTE_ADDR
# may not qualify the remote addr:
# http://www.ietf.org/rfc/rfc3875
if isinstance(client, string_types):
environ['REMOTE_ADDR'] = client
else:
remote = forward

environ['REMOTE_ADDR'] = remote[0]
environ['REMOTE_PORT'] = str(remote[1])
environ['REMOTE_ADDR'] = client[0]
environ['REMOTE_PORT'] = str(client[1])

if isinstance(server, string_types):
server = server.split(":")
Expand Down

0 comments on commit c487368

Please sign in to comment.