In this article, we'll be discussing a vulnerability (CVE-2022-29167) in the Hawk HTTP authentication scheme, which is commonly used for making authenticated HTTP requests with partial cryptographic verification. We'll go over the details of the vulnerability, show a code snippet demonstrating the issue, and provide links to the original references. Furthermore, we'll delve into the exploit, how it works, and the patch that was released to fix the problem. We'll use simple, easy-to-understand language to make the content engaging and exclusive.

What is Hawk?

Hawk is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with partial cryptographic verification of the request and response. It covers the HTTP method, request URI, host, and optionally the request payload. Hawk is a popular choice for securing web applications that require strict access controls and privacy.

The Vulnerability: CVE-2022-29167

The vulnerability in question is related to the parsing of the Host HTTP header in Hawk's utils.parseHost() function. This function utilized a regular expression to parse the header, which could be exploited by an attacker to perform a regular expression Denial of Service (ReDoS) attack. In a ReDoS attack, each added character in the attacker's input increases the computation time exponentially, potentially bringing the server to a grinding halt.

Here is the vulnerable code snippet

Hawk.utils.parseHost = function (req) {
    const hostHeader = req.headers.host;
    const hostHeaderRegex = /^(?:(?:\[((?:[a-f-9:]+))(?:%.*)?\]))(?::(\d+))?|^((?:[a-zA-Z-9\-._~%!$&'()*+,;=]+))(?::(\d+))?$/;
    const hostParts = hostHeader.match(hostHeaderRegex);
};

The Exploit

An attacker could exploit the vulnerability by crafting an HTTP request with a specifically designed Host header that makes the server spend an excessive amount of time parsing the header. Here's an example of such an HTTP request:

GET /path HTTP/1.1
Host: very-long-and-malicious-hostname.com
Authorization: Hawk ...

The very-long-and-malicious-hostname.com in the above request would trigger the ReDoS attack.

To mitigate this vulnerability, Hawk authenticate() function accepts options argument, which can contain host and port. If provided, these values will be used instead of the utils.parseHost() function call:

Hawk.authenticate = function (req, options) {
    const host = options.host || Hawk.utils.parseHost(req);
    const port = options.port;
};

However, this is not a complete solution. The vulnerability still exists, and an attacker could bypass this protection by crafting an HTTP request without the host and port headers, forcing the server to fall back to the vulnerable utils.parseHost() function.

The Patch

To fix the vulnerability, Hawk developers released version 9..1, which replaces the regular expression used in the utils.parseHost() function with the built-in URL class for parsing the hostname. Here's the patched code snippet:

Hawk.utils.parseHost = function (req) {
    const hostHeader = req.headers.host;
    const url = new URL(http://${hostHeader});
    return {hostname: url.hostname, port: url.port};
};

This patch effectively prevents ReDoS attacks by using the built-in URL class, which provides efficient parsing of hostnames and eliminates the need for the vulnerable regular expression.

Conclusion

The vulnerability CVE-2022-29167 was a notable finding in the Hawk HTTP authentication scheme, allowing attackers to take advantage of a ReDoS exploit. Thankfully, the developers quickly released a patch that replaced the vulnerable code with a more efficient solution using the built-in URL class for parsing hostnames. It is crucial for users to ensure they are using the latest version of the Hawk library (v9..1 or later) to protect their web applications against potential attacks.

Original References

- Hawk GitHub Repository - https://github.com/hueniverse/hawk
- Vulnerability Details and Patch - Hawk GitHub Pull Request #261
- Regular Expression Denial of Service - OWASP ReDoS

Timeline

Published on: 05/05/2022 23:15:00 UTC
Last modified on: 05/16/2022 16:58:00 UTC