@@ -12,6 +12,7 @@ import akka.http.impl.engine.http2.Http2Protocol.ErrorCode
12
12
import akka .http .impl .engine .http2 .Http2Protocol .Flags
13
13
import akka .http .impl .engine .http2 .Http2Protocol .FrameType
14
14
import akka .http .impl .engine .http2 .Http2Protocol .SettingIdentifier
15
+ import akka .http .impl .engine .http2 .framing .FrameRenderer
15
16
import akka .http .impl .engine .server .{ HttpAttributes , ServerTerminator }
16
17
import akka .http .impl .engine .ws .ByteStringSinkProbe
17
18
import akka .http .impl .util .AkkaSpecWithMaterializer
@@ -22,28 +23,29 @@ import akka.http.scaladsl.model._
22
23
import akka .http .scaladsl .model .headers .CacheDirectives
23
24
import akka .http .scaladsl .model .headers .RawHeader
24
25
import akka .http .scaladsl .settings .ServerSettings
25
- import akka .stream .Attributes
26
+ import akka .stream .{ Attributes , DelayOverflowStrategy , OverflowStrategy }
26
27
import akka .stream .Attributes .LogLevels
27
- import akka .stream .OverflowStrategy
28
28
import akka .stream .scaladsl .{ BidiFlow , Flow , Keep , Sink , Source , SourceQueueWithComplete }
29
29
import akka .stream .testkit .TestPublisher .{ ManualProbe , Probe }
30
30
import akka .stream .testkit .scaladsl .StreamTestKit
31
31
import akka .stream .testkit .TestPublisher
32
32
import akka .stream .testkit .TestSubscriber
33
33
import akka .testkit ._
34
- import akka .util .ByteString
34
+ import akka .util .{ ByteString , ByteStringBuilder }
35
35
36
36
import scala .annotation .nowarn
37
37
import javax .net .ssl .SSLContext
38
38
import org .scalatest .concurrent .Eventually
39
39
import org .scalatest .concurrent .PatienceConfiguration .Timeout
40
40
41
+ import java .nio .ByteOrder
41
42
import scala .collection .immutable
42
43
import scala .concurrent .duration ._
43
44
import scala .concurrent .Await
44
45
import scala .concurrent .ExecutionContext
45
46
import scala .concurrent .Future
46
47
import scala .concurrent .Promise
48
+ import scala .util .Success
47
49
48
50
/**
49
51
* This tests the http2 server protocol logic.
@@ -1686,6 +1688,31 @@ class Http2ServerSpec extends AkkaSpecWithMaterializer("""
1686
1688
terminated.futureValue
1687
1689
}
1688
1690
}
1691
+
1692
+ " not allow high a frequency of resets for one connection" in StreamTestKit .assertAllStagesStopped(new TestSetup {
1693
+
1694
+ override def settings : ServerSettings = super .settings.withHttp2Settings(super .settings.http2Settings.withMaxResets(100 ).withMaxResetsInterval(2 .seconds))
1695
+
1696
+ // covers CVE-2023-44487 with a rapid sequence of RSTs
1697
+ override def handlerFlow : Flow [HttpRequest , HttpResponse , NotUsed ] = Flow [HttpRequest ].buffer(1000 , OverflowStrategy .backpressure).mapAsync(300 ) { req =>
1698
+ // never actually reached since rst is in headers
1699
+ req.entity.discardBytes()
1700
+ Future .successful(HttpResponse (entity = " Ok" ).withAttributes(req.attributes))
1701
+ }
1702
+
1703
+ network.toNet.request(100000L )
1704
+ val request = HttpRequest (protocol = HttpProtocols .`HTTP/2.0`, uri = " /foo" )
1705
+ val error = intercept[AssertionError ] {
1706
+ for (streamId <- 1 to 300 by 2 ) {
1707
+ network.sendBytes(
1708
+ FrameRenderer .render(HeadersFrame (streamId, true , true , network.encodeRequestHeaders(request), None ))
1709
+ ++ FrameRenderer .render(RstStreamFrame (streamId, ErrorCode .CANCEL ))
1710
+ )
1711
+ }
1712
+ }
1713
+ error.getMessage should include(" Too many RST frames per second for this connection." )
1714
+ network.toNet.cancel()
1715
+ })
1689
1716
}
1690
1717
1691
1718
implicit class InWithStoppedStages (name : String ) {
0 commit comments