VYPR
Critical severityNVD Advisory· Published Nov 4, 2024· Updated Apr 15, 2026

CVE-2024-51501

CVE-2024-51501

Description

Refit is an automatic type-safe REST library for .NET Core, Xamarin and .NET The various header-related Refit attributes (Header, HeaderCollection and Authorize) are vulnerable to CRLF injection. The way HTTP headers are added to a request is via the HttpHeaders.TryAddWithoutValidation method. 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. 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 and not in Refit itself. This issue has been addressed in release versions 7.2.22 and 8.0.0 and all users are advised to upgrade. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
RefitNuGet
< 7.2.227.2.22

Patches

2
483b1d8df180

Fix for CRLF injection vulnerability (#1834)

https://github.com/reactiveui/refitChris PulmanSep 22, 2024via ghsa
3 files changed · +54 1
  • Refit/RequestBuilderImplementation.cs+13 1 modified
    @@ -977,7 +977,7 @@ static void AddHeadersToRequest(Dictionary<string, string?>? headersToAdd, HttpR
                 // sure we have an HttpContent object to add them to,
                 // provided the HttpClient will allow it for the method
                 if (ret.Content == null && !IsBodyless(ret.Method))
    -                ret.Content = new ByteArrayContent(Array.Empty<byte>());
    +                ret.Content = new ByteArrayContent([]);
     
                 foreach (var header in headersToAdd)
                 {
    @@ -1335,6 +1335,10 @@ static void SetHeader(HttpRequestMessage request, string name, string? value)
                 if (value == null)
                     return;
     
    +            // CRLF injection protection
    +            name = EnsureSafe(name);
    +            value = EnsureSafe(value);
    +
                 var added = request.Headers.TryAddWithoutValidation(name, value);
     
                 // Don't even bother trying to add the header as a content header
    @@ -1345,6 +1349,14 @@ static void SetHeader(HttpRequestMessage request, string name, string? value)
                 }
             }
     
    +        static string EnsureSafe(string value)
    +        {
    +            // Remove CR and LF characters
    +#pragma warning disable CA1307 // Specify StringComparison for clarity
    +            return value.Replace("\r", string.Empty).Replace("\n", string.Empty);
    +#pragma warning restore CA1307 // Specify StringComparison for clarity
    +        }
    +
             static bool IsBodyless(HttpMethod method) => method == HttpMethod.Get || method == HttpMethod.Head;
         }
     }
    
  • Refit/RestMethodInfo.cs+6 0 modified
    @@ -259,6 +259,12 @@ static void VerifyUrlPathIsSane(string relativePath)
                     throw new ArgumentException(
                         $"URL path {relativePath} must start with '/' and be of the form '/foo/bar/baz'"
                     );
    +
    +            // CRLF injection protection
    +            if (relativePath.Contains("\r") || relativePath.Contains("\n"))
    +                throw new ArgumentException(
    +                    $"URL path {relativePath} must not contain CR or LF characters"
    +                );
             }
     
             static Dictionary<int, RestMethodParameterInfo> BuildParameterMap(
    
  • Refit.Tests/AuthenticatedClientHandlerTests.cs+35 0 modified
    @@ -4,8 +4,11 @@
     using System.Net.Http;
     using System.Text;
     using System.Threading.Tasks;
    +
     using Refit; // for the code gen
    +
     using RichardSzalay.MockHttp;
    +
     using Xunit;
     
     namespace Refit.Tests;
    @@ -49,6 +52,12 @@ public interface IInheritedAuthenticatedServiceWithHeaders : IAuthenticatedServi
             Task<string> GetInheritedThing();
         }
     
    +    public interface IInheritedAuthenticatedServiceWithHeadersCRLF : IAuthenticatedServiceWithHeaders
    +    {
    +        [Get("/get-inherited-thing\r\n\r\nGET /smuggled")]
    +        Task<string> GetInheritedThing();
    +    }
    +
         [Headers("Authorization: Bearer")]
         public interface IAuthenticatedServiceWithHeaders
         {
    @@ -347,4 +356,30 @@ public async void AuthentictedMethodFromInheritedClassWithHeadersAttributeUsesAu
     
             Assert.Equal("Ok", result);
         }
    +
    +    [Fact]
    +    public async void AuthentictedMethodFromInheritedClassWithHeadersAttributeUsesAuth_WithCRLFCheck()
    +    {
    +        var handler = new MockHttpMessageHandler();
    +        var settings = new RefitSettings()
    +        {
    +            AuthorizationHeaderValueGetter = (_, __) => Task.FromResult("tokenValue"),
    +            HttpMessageHandlerFactory = () => handler,
    +        };
    +
    +        handler
    +            .Expect(HttpMethod.Get, "http://api/get-inherited-thing")
    +            .WithHeaders("Authorization", "Bearer tokenValue")
    +            .Respond("text/plain", "Ok");
    +
    +        await Assert.ThrowsAsync<ArgumentException>(async () =>
    +        {
    +            var fixture = RestService.For<IInheritedAuthenticatedServiceWithHeadersCRLF>(
    +                    "http://api",
    +                    settings
    +                );
    +
    +            var result = await fixture.GetInheritedThing();
    +        });
    +    }
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.