Every CVE Search/ Get API key

CVE-2026-34715

ewe Has Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting)

5.3 MediumFix available

ewe is a Gleam web server. Prior to version 3.0.6, the encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting. Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder. This issue has been patched in version 3.0.6.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
Low
Availability
None

Exploit likelihood

0.34%Up 0.3 points since Apr 3, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.3

ewe Has Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting)

ewe is a Gleam web server. Prior to version 3.0.6, the encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting. Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder. This issue has been patched in version 3.0.6.

Record
CVE-2026-34715
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-113
Updated
2026-11-02
EUVDEUVD-2026-18468 5.3

ewe is a Gleam web server. Prior to version 3.0.6, the encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting. Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder. This issue has been patched in version 3.0.6.

Record
EUVD-2026-18468
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-x2w3-23jr-hrpf 5.3

ewe Has Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting)

Summary

The encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting.

Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder.

Details

File: src/ewe/internal/encoder.gleam

Vulnerable code:

fn encode_headers(headers: List(#(String, String))) -> BitArray {
  let headers =
    list.fold(headers, <<>>, fn(acc, headers) {
      let #(key, value) = headers
      <<acc:bits, key:utf8, ": ", value:utf8, "\r\n">>
    })

  <<headers:bits, "\r\n">>
}

Both key and value are embedded directly into the BitArray output. If either contains \r\n, the resulting bytes become a structurally valid but attacker-controlled HTTP response, terminating the current header early and injecting new headers or a second HTTP response.

Contrast with request parsing (src/ewe/internal/http1.gleam): incoming header values are protected:

use value <- try(
  validate_field_value(value) |> replace_error(InvalidHeaders)
)

No analogous validation exists for outgoing header values in the encoder. The solution is to strip or reject \r (0x0D) and \n (0x0A) from all header key and value strings in encode_headers before encoding, mirroring the validation already applied to incoming request headers via validate_field_value()

PoC

An ewe application echoes a user-supplied redirect URL into a Location header:

fn handle_request(req: Request) -> Response {
  let redirect_url =
    request.get_query(req)
    |> result.try(list.key_find(_, "next"))
    |> result.unwrap("/home")

  response.new(302)
  |> response.set_header("location", redirect_url)
  |> response.set_body(ewe.Empty)
}

Attacker request:

printf 'GET /?next=https://example.com%%0d%%0aX-Injected:%%20true HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc -w 2 localhost 8080

Resulting response:

HTTP/1.1 302 Found
location: https://example.com
X-Injected: true
content-length: 0
date: Tue, 24 Mar 2026 07:53:00 GMT
connection: keep-alive


The X-Injected: true header appears as a separate response header, confirming that CRLF sequences in user input are not sanitized by the encoder.

Record
GHSA-x2w3-23jr-hrpf
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-113
Updated
2026-11-02
NVD 5.3

ewe is a Gleam web server. Prior to version 3.0.6, the encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting. Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder. This issue has been patched in version 3.0.6.

Record
CVE-2026-34715
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-113
Updated
2026-11-02
OSV 5.3

ewe Has Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting)

ewe is a Gleam web server. Prior to version 3.0.6, the encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting. Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder. This issue has been patched in version 3.0.6.

Record
CVE-2026-34715
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-113
Updated
2026-11-02
OSVGHSA-x2w3-23jr-hrpf 5.3

ewe Has Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting)

Summary

The encode_headers function in src/ewe/internal/encoder.gleam directly interpolates response header keys and values into raw HTTP bytes without validating or stripping CRLF (\r\n) sequences. An application that passes user-controlled data into response headers (e.g., setting a Location redirect header from a request parameter) allows an attacker to inject arbitrary HTTP response content, leading to response splitting, cache poisoning, and possible cross-site scripting.

Notably, ewe does validate CRLF in incoming request headers via validate_field_value() in the HTTP/1.1 parser — but provides no equivalent protection for outgoing response headers in the encoder.

Details

File: src/ewe/internal/encoder.gleam

Vulnerable code:

fn encode_headers(headers: List(#(String, String))) -> BitArray {
  let headers =
    list.fold(headers, <<>>, fn(acc, headers) {
      let #(key, value) = headers
      <<acc:bits, key:utf8, ": ", value:utf8, "\r\n">>
    })

  <<headers:bits, "\r\n">>
}

Both key and value are embedded directly into the BitArray output. If either contains \r\n, the resulting bytes become a structurally valid but attacker-controlled HTTP response, terminating the current header early and injecting new headers or a second HTTP response.

Contrast with request parsing (src/ewe/internal/http1.gleam): incoming header values are protected:

use value <- try(
  validate_field_value(value) |> replace_error(InvalidHeaders)
)

No analogous validation exists for outgoing header values in the encoder. The solution is to strip or reject \r (0x0D) and \n (0x0A) from all header key and value strings in encode_headers before encoding, mirroring the validation already applied to incoming request headers via validate_field_value()

PoC

An ewe application echoes a user-supplied redirect URL into a Location header:

fn handle_request(req: Request) -> Response {
  let redirect_url =
    request.get_query(req)
    |> result.try(list.key_find(_, "next"))
    |> result.unwrap("/home")

  response.new(302)
  |> response.set_header("location", redirect_url)
  |> response.set_body(ewe.Empty)
}

Attacker request:

printf 'GET /?next=https://example.com%%0d%%0aX-Injected:%%20true HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc -w 2 localhost 8080

Resulting response:

HTTP/1.1 302 Found
location: https://example.com
X-Injected: true
content-length: 0
date: Tue, 24 Mar 2026 07:53:00 GMT
connection: keep-alive


The X-Injected: true header appears as a separate response header, confirming that CRLF sequences in user input are not sanitized by the encoder.

Record
GHSA-x2w3-23jr-hrpf
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-113
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
ewe
Hex
before 3.0.6
3.0.6
ewe
Hex
before 3.0.6, plus listed versions
0.0.10.0.20.1.00.10.00.2.0
Show 26 moreShow less
0.3.00.4.00.5.00.6.00.7.00.8.00.8.10.9.01.0.01.0.0-rc11.0.0-rc21.0.12.0.02.0.12.0.22.0.32.1.02.1.12.1.22.1.33.0.03.0.13.0.23.0.33.0.43.0.5
3.0.6

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-34715 is a medium vulnerability (CVSS 5.3) in Vshakitskiy Ewe, published April 1, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.34%, the 27th percentile. Fixed in ewe 3.0.6.

References

MoveEnter Open