Skip to content

Commit 7c45f84

Browse files
authored
Reject invalid HTTP methods and resources (#1019)
This change addresses the issue that currently, any HTTP method is handled by returning success and metrics data, which causes network scanners to report issues. Details: * This change rejects any HTTP methods and resources other than the following: OPTIONS (any) - returns 200 and an 'Allow' header indicating allowed methods GET (any) - returns 200 and metrics GET /favicon.ico - returns 200 and no body (this is no change) Other HTTP methods than these are rejected with 405 "Method Not Allowed" and an 'Allow' header indicating the allowed HTTP methods. Any returned HTTP errors are also displayed in the response body after a hash sign and with a brief hint, e.g. "# HTTP 405 Method Not Allowed: XXX; use OPTIONS or GET". Signed-off-by: Andreas Maier <[email protected]>
1 parent 09a5ae3 commit 7c45f84

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

docs/content/exporting/http/_index.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,23 @@ chain is used (see Python [ssl.SSLContext.load_default_certs()](https://docs.pyt
5252
from prometheus_client import start_http_server
5353

5454
start_http_server(8000, certfile="server.crt", keyfile="server.key")
55-
```
55+
```
56+
57+
# Supported HTTP methods
58+
59+
The prometheus client will handle the following HTTP methods and resources:
60+
61+
* `OPTIONS (any)` - returns HTTP status 200 and an 'Allow' header indicating the
62+
allowed methods (OPTIONS, GET)
63+
* `GET (any)` - returns HTTP status 200 and the metrics data
64+
* `GET /favicon.ico` - returns HTTP status 200 and an empty response body. Some
65+
browsers support this to display the returned icon in the browser tab.
66+
67+
Other HTTP methods than these are rejected with HTTP status 405 "Method Not Allowed"
68+
and an 'Allow' header indicating the allowed methods (OPTIONS, GET).
69+
70+
Any returned HTTP errors are also displayed in the response body after a hash
71+
sign and with a brief hint. Example:
72+
```
73+
# HTTP 405 Method Not Allowed: XXX; use OPTIONS or GET
74+
```

prometheus_client/exposition.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,24 @@ def prometheus_app(environ, start_response):
118118
accept_header = environ.get('HTTP_ACCEPT')
119119
accept_encoding_header = environ.get('HTTP_ACCEPT_ENCODING')
120120
params = parse_qs(environ.get('QUERY_STRING', ''))
121-
if environ['PATH_INFO'] == '/favicon.ico':
121+
method = environ['REQUEST_METHOD']
122+
123+
if method == 'OPTIONS':
124+
status = '200 OK'
125+
headers = [('Allow', 'OPTIONS,GET')]
126+
output = b''
127+
elif method != 'GET':
128+
status = '405 Method Not Allowed'
129+
headers = [('Allow', 'OPTIONS,GET')]
130+
output = '# HTTP {}: {}; use OPTIONS or GET\n'.format(status, method).encode()
131+
elif environ['PATH_INFO'] == '/favicon.ico':
122132
# Serve empty response for browsers
123133
status = '200 OK'
124134
headers = [('', '')]
125135
output = b''
126136
else:
137+
# Note: For backwards compatibility, the URI path for GET is not
138+
# constrained to the documented /metrics, but any path is allowed.
127139
# Bake output
128140
status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
129141
# Return output

0 commit comments

Comments
 (0)