Skip to content

TOR-028 pen-project#28: sbws - HTTPS Downgrade Attack via HTTP redirects

Technical Description

The sbws scanner command builds circuits and measures relays' bandwidth by downloading/uploading data from destination entries in the config. However, multiple destinations can be defined, including services offering download files. To perform a measurement, the function timed_recv_from_server is used to download a file from a destination and to track the elapsed time. The corresponding HTTP client was previously created using the make_session function and utilizes the requests library. However, this library follows HTTP redirects by default, which allows a malicious destination to redirect the client to another host and downgrade from HTTPS to HTTP.

For example, an attacker could downgrade another destination from HTTPS to HTTP while measuring the malicious destination. Each connection passes through Tor, allowing malicious exit-node operators to perform a man-in-the-middle attack between the exit node and the redirected destination because of the downgrade. This is especially critical if, for example, API tokens or other secret HTTP request headers are configured only for specific destinations. In the worst case, this can lead to leaked secrets and thus form the basis for further attacks.

tpo/network-health/sbws/core/scanner.py

def timed_recv_from_server(session, dest, byte_range):
    start_time = time.monotonic()
    HTTP_GET_HEADERS["Range"] = byte_range
    try:
        session.get(dest.url, headers=HTTP_GET_HEADERS, verify=dest.verify)

tpo/network-health/sbws/util/requests.py

class TimedSession(requests.Session):
    def get(self, url, **kwargs):
        return super().get(
            url, timeout=getattr(self, "_timeout", None, ), **kwargs
        )

def make_session(controller, timeout):
    s = TimedSession()
    socks_info = stem_utils.get_socks_info(controller)
    s.proxies = {
        "http": "socks5h://{}:{}".format(*socks_info),
        "https": "socks5h://{}:{}".format(*socks_info),
    }
    s._timeout = timeout
    s.headers = settings.HTTP_HEADERS
    return s

Impact

Attackers controlling a destination could perform an HTTPS downgrade attack on HTTP, potentially allowing malicious exit nodes (the attacker) to leak secret tokens configured only for specific destinations. However, when writing this report, all destinations are treated equally, not giving attackers a significant advantage. But this may change in the future as this project evolves.

Recommendation

It is recommended to follow redirects only if desired and to ignore a redirect from HTTPS to HTTP.

Type

CWE-757: Selection of Less-Secure Algorithm During Negotiation ('Algorithm Downgrade')