-
Notifications
You must be signed in to change notification settings - Fork 271
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
364 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
================== | ||
WSGITrustedProxies | ||
================== | ||
|
||
:Description: Specify a list of trusted proxies. | ||
:Syntax: ``WSGITrustedProxies`` *ipaddr|(ipaddr-1 ipaddr-2 ...)* | ||
:Context: server config, virtual host, directory, .htaccess | ||
:Override: ``FileInfo`` | ||
|
||
Used to specify a list of IP addresses for proxies placed in front of the | ||
Apache instance which are trusted. | ||
|
||
This directive only has effect when used in conjunction with the | ||
``WSGITrustedProxyHeaders`` directive. For more details see the documentation | ||
for the ``WSGITrustedProxyHeaders`` directive. |
231 changes: 231 additions & 0 deletions
231
docs/configuration-directives/WSGITrustedProxyHeaders.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
======================= | ||
WSGITrustedProxyHeaders | ||
======================= | ||
|
||
:Description: Specify a list of trusted proxy headers. | ||
:Syntax: ``WSGITrustedProxyHeaders`` *header|(header-1 header-2 ...)* | ||
:Context: server config, virtual host, directory, .htaccess | ||
:Override: ``FileInfo`` | ||
|
||
When trusted proxies are designated, this is used to specify the headers | ||
which are used to convey information from a proxy to a web server behind the | ||
proxy that are to be trusted. | ||
|
||
The IP addresses of the proxies to be trusted should be specified using the | ||
``WSGITrustedProxies`` directive. | ||
|
||
As there are multiple conventions for what headers are used to convey | ||
information from the proxy to the web server you need to specify the specific | ||
header from a supported list of headers for a particular purpose that you want | ||
to trust using the ``WSGITrustedProxyHeaders`` directive. | ||
|
||
When a request is then received from a trusted proxy, only the header from | ||
the set of headers for that particular purpose is passed through to the WSGI | ||
application and all others will be dropped. If a request was instead from an | ||
IP address which isn't a trusted proxy, then all headers in that set of headers | ||
will be dropped and not passed through. | ||
|
||
Depending on the purpose of the header, modifications will be made to other | ||
special variables passed through to the WSGI application. It is these other | ||
variables which is what the WSGI application should consult and the original | ||
header should never be consulted, with it only being provided as an indication | ||
of which header was used to set the special variable. | ||
|
||
The different sets of supported headers used by proxies are as follows. | ||
|
||
For passing through the IP address of the remote HTTP client the supported | ||
headers are: | ||
|
||
* X-Forwarded-For | ||
* X-Client-IP | ||
* X-Real-IP | ||
|
||
You should select only one of these headers as the authoritative source for | ||
the IP address of the remote HTTP client as sent by the proxy. Never select | ||
multiple headers because if you do which will be used is indeterminate. | ||
|
||
The de-facto standard for this type of header is ``X-Forwarded-For`` and it | ||
is recommended that it be used if your proxy supports it. | ||
|
||
The configuration might therefore be:: | ||
|
||
WSGITrustedProxies 1.2.3.4 | ||
WSGITrustedProxyHeaders X-Forwarded-For | ||
|
||
With this configuration, when a request is received from the trusted proxy only | ||
the ``X-Forwarded-For`` header will be passed through to the WSGI application. | ||
This will be done following CGI convention as used by WSGI, namely in the | ||
``HTTP_X_FORWARDED_FOR`` variable. | ||
|
||
For this set of headers, the ``REMOTE_ADDR`` CGI variable as used by WSGI will | ||
be modified and set to the IP address of the remote HTTP client. A WSGI | ||
application in this case should always use ``REMOTE_ADDR`` and never consult | ||
the original header files. | ||
|
||
For passing through the protocol of the original request received by the | ||
trusted proxy the supported headers are: | ||
|
||
* X-Forwarded-HTTPS | ||
* X-Forwarded-Proto | ||
* X-Forwarded-Scheme | ||
* X-Forwarded-SSL | ||
* X-HTTPS | ||
* X-Scheme | ||
|
||
You should select only one of these headers as the authoritative source for what | ||
protocol was used by the remote HTTP client as sent by the proxy. Never select | ||
multiple headers because if you do which will be used is indeterminate. | ||
|
||
The de-facto standard for this type of header is ``X-Forwarded-Proto`` and it | ||
is recommended that it be used if your proxy supports it. | ||
|
||
The configuration might therefore be:: | ||
|
||
WSGITrustedProxies 1.2.3.4 | ||
WSGITrustedProxyHeaders X-Forwarded-Proto | ||
|
||
With this configuration, when a request is received from the trusted proxy only | ||
the ``X-Forwarded-Proto`` header will be passed through to the WSGI application. | ||
This will be done following CGI convention as used by WSGI, namely in the | ||
``HTTP_X_FORWARDED_PROTO`` variable. | ||
|
||
For this set of headers, the ``wsgi.url_scheme`` variable passed to the WSGI | ||
application will be modified to indicate whether the original request used the | ||
``https`` protocol. Note that although it is a convention when using CGI | ||
scripts with Apache, the mod_wsgi module removes the ``HTTPS`` variable from | ||
the set of variables passed to the WSGI application. You should always use | ||
the ``wsgi.url_scheme`` variable in a WSGI application. | ||
|
||
For passing through the host name targeted by the original request received by | ||
the trusted proxy the supported headers are: | ||
|
||
* X-Forwarded-Host | ||
* X-Host | ||
|
||
You should select only one of these headers as the authoritative source for the | ||
host targeted by the original request as sent by the proxy. Never select | ||
multiple headers because if you do which will be used is indeterminate. | ||
|
||
The de-facto standard for this type of header is ``X-Forwarded-Host`` and it | ||
is recommended that it be used if your proxy supports it. | ||
|
||
The configuration might therefore be:: | ||
|
||
WSGITrustedProxies 1.2.3.4 | ||
WSGITrustedProxyHeaders X-Forwarded-Host | ||
|
||
With this configuration, when a request is received from the trusted proxy only | ||
the ``X-Forwarded-Host`` header will be passed through to the WSGI application. | ||
This will be done following CGI convention as used by WSGI, namely in the | ||
``HTTP_X_FORWARDED_HOST`` variable. | ||
|
||
For this set of headers, the ``HTTP_HOST`` variable passed to the WSGI | ||
application will be overridden with the value from the header supplied by the | ||
proxy. That is, the value from the proxy for the original request will even | ||
override any explicit ``Host`` header supplied in the request from the proxy, | ||
which in normal cases would be the host of the web server. A WSGI application | ||
should always consult the ``HTTP_HOST`` variable and not the separate header | ||
supplied by the proxy. | ||
|
||
For passing through the port targeted by the original request received by the | ||
trusted proxy, the only supported header is: | ||
|
||
* X-Forwarded-Port | ||
|
||
Although it is the only supported header, you still must select if as a trusted | ||
header to have it processed in the same way as other trusted headers. | ||
|
||
The configuration might therefore be:: | ||
|
||
WSGITrustedProxies 1.2.3.4 | ||
WSGITrustedProxyHeaders X-Forwarded-Port | ||
|
||
With this configuration, when a request is received from the trusted proxy only | ||
the ``X-Forwarded-Port`` header will be passed through to the WSGI application. | ||
This will be done following CGI convention as used by WSGI, namely in the | ||
``HTTP_X_FORWARDED_PORT`` variable. | ||
|
||
For this header, the ``SERVER_PORT`` variable passed to the WSGI application | ||
will be overridden with the value from the header supplied by the proxy. A WSGI | ||
application should always consult the ``SERVER_PORT`` variable and not the | ||
separate header supplied by the proxy. | ||
|
||
For passing through the host name of any proxy, to use in overriding the host | ||
name of the web server, the only supported header is: | ||
|
||
* X-Forwarded-Server | ||
|
||
Although it is the only supported header, you still must select if as a trusted | ||
header to have it processed in the same way as other trusted headers. | ||
|
||
The configuration might therefore be:: | ||
|
||
WSGITrustedProxies 1.2.3.4 | ||
WSGITrustedProxyHeaders X-Forwarded-Server | ||
|
||
With this configuration, when a request is received from the trusted proxy only | ||
the ``X-Forwarded-Server`` header will be passed through to the WSGI application. | ||
This will be done following CGI convention as used by WSGI, namely in the | ||
``HTTP_X_FORWARDED_SERVER`` variable. | ||
|
||
For this header, the ``SERVER_NAME`` variable passed to the WSGI application | ||
will be overridden with the value from the header supplied by the proxy. A WSGI | ||
application should always consult the ``SERVER_NAME`` variable and not the | ||
separate header supplied by the proxy. | ||
|
||
For passing through the apparent URL sub path of a web application, as mapped | ||
by the trusted proxy, the supported headers are: | ||
|
||
* X-Script-Name | ||
* X-Forwarded-Script-Name | ||
|
||
You should select only one of these headers as the authoritative source for the | ||
host targeted by the original request as sent by the proxy. Never select | ||
multiple headers because if you do which will be used is indeterminate. | ||
|
||
The configuration might therefore be:: | ||
|
||
WSGITrustedProxies 1.2.3.4 | ||
WSGITrustedProxyHeaders X-Script-Name | ||
|
||
With this configuration, when a request is received from the trusted proxy only | ||
the ``X-Script-Name`` header will be passed through to the WSGI application. | ||
This will be done following CGI convention as used by WSGI, namely in the | ||
``HTTP_X_SCRIPT_NAME`` variable. | ||
|
||
For this header, the ``SCRIPT_NAME`` variable passed to the WSGI application | ||
will be overridden with the value from the header supplied by the proxy. A WSGI | ||
application should always consult the ``SCRIPT_NAME`` variable and not the | ||
separate header supplied by the proxy. | ||
|
||
Examples above show using a single header of a specific purpose at one time. | ||
When you need to trust multiple headers for different purposes, you can list | ||
them separated by spaces using one instance of ``WSGITrustedProxyHeaders``:: | ||
|
||
WSGITrustedProxyHeaders X-Forwarded-For X-Forwarded-Host X-Forwarded-Port | ||
|
||
or in separate directives:: | ||
|
||
WSGITrustedProxyHeaders X-Forwarded-For | ||
WSGITrustedProxyHeaders X-Forwarded-Host | ||
WSGITrustedProxyHeaders X-Forwarded-Port | ||
|
||
As already highlighted you should only list one header for a specific purpose | ||
when there are multiple conventions for what header to use. Which you use will | ||
depend on the configuration of your proxy. You should only trust headers which | ||
are always set by the proxy, never trust headers which are optionally set by | ||
proxies because if not overridden by a proxy, a remote client could still | ||
supply the header. | ||
|
||
Also remember that in general you should not consult the proxied headers | ||
themselves, but instead consult the special variables set from those headers | ||
which are passed to the WSGI application and which are defined as being special | ||
to WSGI. As illustration of how such special variables are used, consider | ||
for example the notes in the WSGI specification around URL reconstruction. | ||
|
||
* https://peps.python.org/pep-3333/#url-reconstruction | ||
|
||
Finally, if using this feature to trust proxies and designated headers, do not | ||
enable in any WSGI framework or application separate functionality it may have | ||
for also processing the proxy headers. You should only rely on what mod_wsgi | ||
has done to update variables special to WSGI. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
============= | ||
Version 4.9.3 | ||
============= | ||
|
||
Version 4.9.3 of mod_wsgi can be obtained from: | ||
|
||
https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.9.3 | ||
|
||
Bugs Fixed | ||
---------- | ||
|
||
* When using ``WSGITrustedProxies`` and ``WSGITrustedProxyHeaders`` in the | ||
Apache configuration, or ``--trust-proxy`` and ``--trust-proxy-header`` | ||
options with ``mod_wsgi-express``, if you trusted the ``X-Client-IP`` | ||
header and a request was received from an untrusted client, the header | ||
was not being correctly removed from the set of headers passed through to | ||
the WSGI application. | ||
|
||
This only occurred with the ``X-Client-IP`` header and the same problem was | ||
not present if trusting the ``X-Real-IP`` or ``X-Forwarded-For`` headers. | ||
|
||
The purpose of this feature for trusting a front end proxy was in this | ||
case for the headers: | ||
|
||
* ``X-Client-IP`` | ||
* ``X-Real-IP`` | ||
* ``X-Forwarded-For`` | ||
|
||
and was designed to allow the value of ``REMOTE_ADDR`` passed to the WSGI | ||
application to be rewritten to the IP address that a trusted proxy said | ||
was the real remote address of the client. | ||
|
||
In other words, if a request was received from a proxy the IP address | ||
of which was trusted, ``REMOTE_ADDR`` would be set to the value of the | ||
single designated header out of those listed above which was to be | ||
trusted. | ||
|
||
In the case where the proxy was trusted, in addition to ``REMOTE_ADDR`` | ||
being rewritten, only the trusted header would be passed through. That is, | ||
if ``X-Real-IP`` was the trusted header, then ``HTTP_X_REAL_IP`` would | ||
be passed to the WSGI application, but ``HTTP_X_CLIENT_IP`` and | ||
``HTTP_X_FORWARDED_FOR`` would be dropped if corresponding headers had | ||
also been supplied. That the header used to rewrite ``REMOTE_ADDR`` was | ||
passed through still was only intended for the purpose of documenting | ||
where the value of ``REMOTE_ADDR`` came from. A WSGI application when | ||
relying on this feature should only ever use the value of ``REMOTE_ADDR`` | ||
and should ignore the header passed through. | ||
|
||
The behaviour as described was therefore based on a WSGI application | ||
not at the same time enabling any WSGI or web framework middleware to | ||
try and process any proxy headers a second time and ``REMOTE_ADDR`` | ||
should be the single source of truth. Albeit the headers which were | ||
passed through should have resulted in the same result for ``REMOTE_ADDR`` | ||
if the proxy headers were processed a second time. | ||
|
||
Now in the case of the client a request was received from not being a | ||
trusted proxy, then ``REMOTE_ADDR`` would not be rewritten, and would | ||
be left as the IP of the client, and none of the headers listed above | ||
were supposed to be passed through. | ||
|
||
That ``REMOTE_ADDR`` is not rewritten is implemented correctly when the | ||
client is not a trusted proxy, but of the three headers listed above, | ||
``HTTP_X_CLIENT_ID`` was not being dropped if the corresponding header | ||
was supplied. | ||
|
||
If the WSGI application followed best practice and only relied on the | ||
value of ``REMOTE_ADDR`` as the source of truth for the remote client | ||
address, then that ``HTTP_X_CLIENT_ID`` was not being dropped should | ||
pose no security risk. There would however be a problem if a WSGI | ||
application was still enabling a WSGI or web framework specific middleware | ||
to process the proxy headers a second time even though not required. In this | ||
case, the middleware used by the WSGI application may still trust the | ||
``X-Client-IP`` header and rewrite ``REMOTE_ADDR`` allowing a malicious | ||
client to pretend to have a different IP address. | ||
|
||
In addition to the WSGI application having redundant checks for the proxy | ||
headers, to take advantage of this, a client would also need direct access | ||
to the Apache/mod_wsgi server instance. | ||
|
||
In the case that only clients on your private network behind your proxy | ||
could access the Apache/mod_wsgi server instance, that would imply any | ||
malicious actor already had access to your private network and had access | ||
to hosts in that private network or could attach their own device to that | ||
private network. | ||
|
||
In the case where your Apache/mod_wsgi server instance could be accessed | ||
from the same external networks as a proxy forwarding requests to it, such | ||
as may occur if making use of a CDN proxy cache, a client would still need | ||
to know the direct address used by the Apache/mod_wsgi server instance. | ||
|
||
Note that only one proxy header for designating the IP of a client should | ||
ever be trusted. If you trust more than one, then which will be used if | ||
both are present is undefined as it is dependent on the order that Apache | ||
processes headers. This hasn't changed and as before to avoid ambiguity you | ||
should only trust one of the proxy headers recognised for this purpose. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[build-system] | ||
requires = ["setuptools>=40.8.0", "wheel", "mod_wsgi-httpd==2.4.48.1"] | ||
requires = ["setuptools>=40.8.0", "wheel", "mod_wsgi-httpd==2.4.54.1"] | ||
build-backend = "setuptools.build_meta:__legacy__" |
Oops, something went wrong.