Headline
CVE-2023-22465: Fatal error parsing User-Agent and Server headers
Http4s is a Scala interface for HTTP services. Starting with version 0.1.0 and prior to versions 0.21.34, 0.22.15, 0.23.17, and 1.0.0-M38, the User-Agent
and Server
header parsers are susceptible to a fatal error on certain inputs. In http4s, modeled headers are lazily parsed, so this only applies to services that explicitly request these typed headers. Fixes are released in 0.21.34, 0.22.15, 0.23.17, and 1.0.0-M38. As a workaround, use the weakly typed header interface.
Impact
The User-Agent and Server header parsers are susceptible to a fatal error on certain inputs. In http4s, modeled headers are lazily parsed, so this only applies to services that explicitly request these typed headers.
v0.21.x
val unsafe: Option[`User-Agent`] = req.headers.get(`User-Agent`)
v0.22.x, v0.23.x, v1.x
val unsafe: Option[`User-Agent`] = req.headers.get[`User-Agent`] val alsoUnsafe: Option[`Server`] = req.headers.get[Server]
Patches
Fixes are released in 0.21.34, 0.22.15, 0.23.17, and 1.0.0-M38.
Workarounds****Use the weakly typed header interface****v0.21.x
val safe: Option[Header] = req.headers.get("User-Agent".ci) // but don’t do this val unsafe = header.map(_.parsed)
v0.22.x, v0.23.x, v1.x
val safe: Option[Header] = req.headers.get(ci"User-Agent")
Related news
### Impact The `User-Agent` and `Server` header parsers are susceptible to a fatal error on certain inputs. In http4s, modeled headers are lazily parsed, so this only applies to services that explicitly request these typed headers. #### v0.21.x ```scala val unsafe: Option[`User-Agent`] = req.headers.get(`User-Agent`) ``` #### v0.22.x, v0.23.x, v1.x ```scala val unsafe: Option[`User-Agent`] = req.headers.get[`User-Agent`] val alsoUnsafe: Option[`Server`] = req.headers.get[Server] ``` ### Patches Fixes are released in 0.21.34, 0.22.15, 0.23.17, and 1.0.0-M38. ### Workarounds #### Use the weakly typed header interface ##### v0.21.x ```scala val safe: Option[Header] = req.headers.get("User-Agent".ci) // but don't do this val unsafe = header.map(_.parsed) ``` ##### v0.22.x, v0.23.x, v1.x ```scala val safe: Option[Header] = req.headers.get(ci"User-Agent") ```