VYPR
Low severityNVD Advisory· Published Jun 2, 2026· Updated Jun 2, 2026

CVE-2026-48861

CVE-2026-48861

Description

Improper Neutralization of CRLF Sequences ('CRLF Injection') vulnerability in elixir-mint Mint allows HTTP Request Splitting and HTTP Request Smuggling.

In lib/mint/http1/request.ex, the encode_request_line/2 function splices the caller-supplied method and target arguments directly into the HTTP/1 request line without any character validation: [method, ?\s, target, " HTTP/1.1\r\n"]. An application that forwards attacker-controlled input as the HTTP method or target to Mint.HTTP.request/5 is therefore exposed to request-line CRLF injection: the attacker can terminate the request line early, inject arbitrary headers, and smuggle an entirely separate pipelined HTTP request onto the same TCP connection.

Mint 1.7.0 introduced validate_request_target/2, which rejects CRLF and other control characters in the target by default and closes the path/query vector unless the caller opts out via skip_target_validation: true. The method field remains unvalidated, so the method-based injection is exploitable under the default Mint configuration on all versions.

This issue affects mint: from 0.1.0 before 1.9.0.

Affected products

1

Patches

1
fad091454cbb

Merge commit from fork

https://github.com/elixir-mint/mintEric Meadows-JönssonJun 2, 2026via body-scan
3 files changed · +44 0
  • lib/mint/http1.ex+6 0 modified
    @@ -48,6 +48,8 @@ defmodule Mint.HTTP1 do
     
         * `{:invalid_request_target, target}` - when the request target is invalid.
     
    +    * `{:invalid_request_method, method}` - when the request method is invalid.
    +
         * `:invalid_header` - when headers can't be parsed correctly.
     
         * `{:invalid_header_name, name}` - when a header name is invalid.
    @@ -1176,6 +1178,10 @@ defmodule Mint.HTTP1 do
         "invalid request target: #{inspect(target)}"
       end
     
    +  def format_error({:invalid_request_method, method}) do
    +    "invalid request method: #{inspect(method)}"
    +  end
    +
       def format_error({:invalid_header_name, name}) do
         "invalid header name: #{inspect(name)}"
       end
    
  • lib/mint/http1/request.ex+13 0 modified
    @@ -4,6 +4,8 @@ defmodule Mint.HTTP1.Request do
       import Mint.HTTP1.Parse
     
       def encode(method, target, headers, body) do
    +    validate_method!(method)
    +
         body = [
           encode_request_line(method, target),
           encode_headers(headers),
    @@ -45,6 +47,17 @@ defmodule Mint.HTTP1.Request do
         [Integer.to_string(length, 16), "\r\n", chunk, "\r\n"]
       end
     
    +  defp validate_method!(method) do
    +    _ =
    +      for <<char <- method>> do
    +        unless is_tchar(char) do
    +          throw({:mint, {:invalid_request_method, method}})
    +        end
    +      end
    +
    +    :ok
    +  end
    +
       defp validate_header_name!(name) do
         _ =
           for <<char <- name>> do
    
  • test/mint/http1/request_test.exs+25 0 modified
    @@ -42,6 +42,31 @@ defmodule Mint.HTTP1.RequestTest do
           assert Request.encode("GET", "/", [{"foo", "bar\r\n"}], nil) ==
                    {:error, {:invalid_header_value, "foo", "bar\r\n"}}
         end
    +
    +    test "method with CRLF is rejected" do
    +      method = "GET / HTTP/1.1\r\nX-Smuggled: 1\r\nGET /admin"
    +
    +      assert Request.encode(method, "/", [], nil) ==
    +               {:error, {:invalid_request_method, method}}
    +    end
    +
    +    test "method with a space is rejected" do
    +      assert Request.encode("GET /admin", "/", [], nil) ==
    +               {:error, {:invalid_request_method, "GET /admin"}}
    +    end
    +
    +    test "method with a control character is rejected" do
    +      assert Request.encode("GET\t", "/", [], nil) ==
    +               {:error, {:invalid_request_method, "GET\t"}}
    +    end
    +
    +    test "custom token method is accepted" do
    +      assert encode_request("PROPFIND", "/", [], nil) ==
    +               request_string("""
    +               PROPFIND / HTTP/1.1
    +
    +               """)
    +    end
       end
     
       describe "encode_chunk/1" do
    

Vulnerability mechanics

Root cause

"The HTTP request encoder did not validate the method argument, allowing CRLF sequences to be injected."

Attack vector

An attacker can exploit this vulnerability by controlling the HTTP method argument passed to Mint.HTTP.request/5. By including CRLF sequences within the method string, such as "GET / HTTP/1.1\r\nX-Smuggled: 1\r\nGET /admin", an attacker can terminate the request line prematurely. This allows for the injection of arbitrary headers and the smuggling of a second, fully attacker-controlled HTTP request onto the same connection [ref_id=1].

Affected code

The vulnerability exists in the `encode_request_line/2` function within `lib/mint/http1/request.ex`. This function directly splices the `method` and `target` arguments into the HTTP/1 request line without validation. The fix adds a call to `validate_method!/1` at the beginning of the `encode/4` function in the same file, ensuring the method is validated before being used.

What the fix does

The patch introduces a new `validate_method!/1` function that checks if each character in the method string is a valid token character (tchar) according to RFC 9110. This validation is performed before encoding the request line. Any method containing CRLF, spaces, or other control characters will now result in an `{:invalid_request_method, method}` error, preventing CRLF injection and HTTP request smuggling [patch_id=4518415].

Preconditions

  • inputThe application must forward attacker-controlled input as the HTTP method to Mint.HTTP.request/5.

Generated on Jun 2, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.