Skip to content

Commit

Permalink
validate trusted_hosts during routing
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Nov 13, 2024
1 parent e6547d6 commit e27dc51
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Unreleased
matching. In ``bind_to_environ``, the ``server_name`` parameter is not used
if ``host_matching`` is enabled. If ``default_subdomain`` is set, it is used
if a subdomain could not be determined. :issue:`3005`
- If a request object is passed to ``Map.bind_to_environ``, the host is
validated against ``request.trusted_hosts``. An invalid host will raise a
400 error. :issue:`3007`


Version 3.1.3
Expand Down
19 changes: 15 additions & 4 deletions src/werkzeug/routing/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
from urllib.parse import urljoin
from urllib.parse import urlunsplit

from .._internal import _get_environ
from .._internal import _wsgi_decoding_dance
from ..datastructures import ImmutableDict
from ..datastructures import MultiDict
from ..exceptions import BadHost
from ..exceptions import HTTPException
from ..exceptions import MethodNotAllowed
from ..exceptions import NotFound
from ..sansio.request import Request as SansIORequest
from ..urls import _urlencode
from ..wsgi import get_host
from .converters import DEFAULT_CONVERTERS
Expand Down Expand Up @@ -278,7 +278,9 @@ def bind_to_environ(
``"<invalid>"`` is used.
:param environ: The WSGI environ for the request. Can also be a
``Request`` with an ``environ`` attribute.
``Request`` with an ``environ`` attribute; in that case, its
:attr:`~.Request.host` is accessed to validate its
:attr:`~.Request.trusted_hosts`.
:param server_name: When subdomain matching is enabled and ``subdomain``
is not given, the subdomain is determined by removing this
``host:port`` as a suffix from the request's ``Host``. If the scheme
Expand All @@ -298,6 +300,10 @@ def bind_to_environ(
.. versionchanged:: 3.2
``server_name`` is ignored if ``host_matching`` is enabled.
.. versionchanged:: 3.2
If the ``environ`` argument is a ``Request``, access ``request.host``
to validate``request.trusted_hosts``.
.. versionchanged:: 1.0.0
If ``server_name`` specifies port 443, it will match if the scheme
is ``https`` and ``Host`` does not specify a port.
Expand All @@ -312,8 +318,13 @@ def bind_to_environ(
.. versionchanged:: 0.5
Removed the ``calculate_subdomain`` parameter which was not used.
"""
env = _get_environ(environ)
wsgi_server_name = get_host(env).lower()
if isinstance(environ, SansIORequest):
env = environ.environ
wsgi_server_name = environ.host.lower()
else:
env = environ
wsgi_server_name = get_host(env).lower()

scheme = env["wsgi.url_scheme"]
upgrade = any(
v.strip() == "upgrade"
Expand Down

0 comments on commit e27dc51

Please sign in to comment.