Dear hakkers,
we want to inform you that a bug in Akka HTTP has been found that can be used as a Denial-Of-Service against Akka HTTP servers
when using decodeRequest
and decodeRequestWith
directives on Akka HTTP servers.
As the problem was shared publicly with us we want to give advance notice about it and provide a workaround until the release of fixed versions of Akka HTTP.
Please subscribe to the akka-security mailing list to be notified promptly about future security issues.
When reporting security relevant information, please follow our guidelines for reporting vulnerabilities.
Description
Directives decodeRequest
and decodeRequestWith
which handle compressed request data don’t limit the amount of uncompressed
data flowing out of it. In combination with common request directives like entity(as)
, toStrict
, or formField
, this can lead
to excessive memory usage ultimately leading to an out of memory situation when highly compressed data is received
(so-called “Zip Bomb”).
Any code that uses decodeRequest
or decodeRequestWith
is likely to be affected.
Workaround
Until we publish a fix that will limit the amount of memory by default, you can use this custom directive instead of
decodeRequest
to guard against excessive decompressed data:
Scala:
def safeDecodeRequest(maxBytes: Long): Directive0 =
decodeRequest & mapRequest(_.mapEntity {
case c: HttpEntity.Chunked ⇒ c.copy(chunks = HttpEntity.limitableChunkSource(c.chunks))
case e ⇒ e
}) & withSizeLimit(maxBytes)
And replace all decodeRequest
usages with
safeDecodeRequest(maxDecompressedBytesToSupport)
Java:
RequestEntity chunkedWithLimit(RequestEntity entity) {
if (entity.isChunked())
return
HttpEntities.createChunked(
entity.getContentType(),
akka.http.scaladsl.model.HttpEntity.limitableByteSource(((HttpEntity.Chunked)entity).getDataBytes().asScala()).asJava()
);
else
return entity;
}
Route safeDecodeRequest(long maxBytes, Supplier<Route> inner) {
return
decodeRequest(() ->
mapRequest(req -> req.withEntity(chunkedWithLimit(req.entity())), () ->
withSizeLimit(maxBytes, inner)
)
);
}
And replace all decodeRequest(innerRoute)
with
safeDecodeRequest(maxDecompressedBytesToSupport, innerRoute)
See https://gist.github.com/jrudolph/2be2e6fcde5f7f395b1dacdb6b70baf7 for full code including imports.
Severity
The CVSS score of this vulnerability is 7.3 (High), based on vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:H/RL:W/RC:C.
Rationale for the score:
- A:H: Server runs into OOM, so availability is highly affected.
- E:H: It’s relatively simple to exploit.
Affected Versions
All released Akka HTTP versions are affected:
- 10.1.x <= 10.1.4
- 10.0.x <= 10.0.13
Not affected:
- Play and Lagom applications, even though both are using Akka HTTP as their server backend, remain unaffected by this vulnerability. This is because they implement their own content length validations on top of the underlying models (by using
BodyParser
s).
Fixed Versions
We will release fixed versions as soon as possible.
Happy and safe hakking!
– The Akka Team