Skip to content

Commit

Permalink
Reject invalid HTTP methods and resources (#1019)
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
andy-maier authored Aug 2, 2024
1 parent 09a5ae3 commit 7c45f84
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
21 changes: 20 additions & 1 deletion docs/content/exporting/http/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,23 @@ chain is used (see Python [ssl.SSLContext.load_default_certs()](https://docs.pyt
from prometheus_client import start_http_server

start_http_server(8000, certfile="server.crt", keyfile="server.key")
```
```

# Supported HTTP methods

The prometheus client will handle the following HTTP methods and resources:

* `OPTIONS (any)` - returns HTTP status 200 and an 'Allow' header indicating the
allowed methods (OPTIONS, GET)
* `GET (any)` - returns HTTP status 200 and the metrics data
* `GET /favicon.ico` - returns HTTP status 200 and an empty response body. Some
browsers support this to display the returned icon in the browser tab.

Other HTTP methods than these are rejected with HTTP status 405 "Method Not Allowed"
and an 'Allow' header indicating the allowed methods (OPTIONS, GET).

Any returned HTTP errors are also displayed in the response body after a hash
sign and with a brief hint. Example:
```
# HTTP 405 Method Not Allowed: XXX; use OPTIONS or GET
```
14 changes: 13 additions & 1 deletion prometheus_client/exposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,24 @@ def prometheus_app(environ, start_response):
accept_header = environ.get('HTTP_ACCEPT')
accept_encoding_header = environ.get('HTTP_ACCEPT_ENCODING')
params = parse_qs(environ.get('QUERY_STRING', ''))
if environ['PATH_INFO'] == '/favicon.ico':
method = environ['REQUEST_METHOD']

if method == 'OPTIONS':
status = '200 OK'
headers = [('Allow', 'OPTIONS,GET')]
output = b''
elif method != 'GET':
status = '405 Method Not Allowed'
headers = [('Allow', 'OPTIONS,GET')]
output = '# HTTP {}: {}; use OPTIONS or GET\n'.format(status, method).encode()
elif environ['PATH_INFO'] == '/favicon.ico':
# Serve empty response for browsers
status = '200 OK'
headers = [('', '')]
output = b''
else:
# Note: For backwards compatibility, the URI path for GET is not
# constrained to the documented /metrics, but any path is allowed.
# Bake output
status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
# Return output
Expand Down

0 comments on commit 7c45f84

Please sign in to comment.