Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP/2 rapid reset mitigation #344

Closed
wants to merge 10 commits into from

Conversation

pjfanning
Copy link
Contributor

@pjfanning pjfanning commented Oct 29, 2023

  • CVE-2023-44487 #332
  • adds a throttle and the connection is closed if the reset frame rate is too high
  • code is largely based on suggestions from @jrudolph
  • the mima filter had to be added due to the new fields in Http2Settings
  • the mima check did not work so I copied over the working MiMa.scala from incubator-pekko repo

@jrudolph
Copy link
Contributor

Thanks for setting that up and sorry for dropping the ball here.

@pjfanning pjfanning force-pushed the http2-reset-frame branch 2 times, most recently from e271157 to efd0bd8 Compare November 8, 2023 19:12
@pjfanning pjfanning changed the title [DRAFT] HTTP/2 rapid reset mitigation HTTP/2 rapid reset mitigation Nov 8, 2023
@pjfanning pjfanning requested review from jrudolph, mdedetrich, raboof, He-Pin and nvollmar and removed request for mdedetrich November 8, 2023 21:06
@pjfanning
Copy link
Contributor Author

@jrudolph @raboof @nvollmar @kerr @gmethvin @mdedetrich would any of you have time to review this? This is a reaction to the Akka team issuing a security warning. I would favour not getting a CVE or attaching our name to the existing CVE-2023-44487 but I'm not against it either. My priority is just to get out a release with some change.

project/MiMa.scala Outdated Show resolved Hide resolved
case _: FrameEvent.DataFrame => 0
case _: FrameEvent.WindowUpdateFrame => 0 // TODO: should we throttle these?
case _ => 1
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be contantFunc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what constantFunc means. Do you mean making this a val instead of a def?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, make just like the Keep.left/right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 7156492 the sort of change that you want?

Copy link
Contributor

@mdedetrich mdedetrich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In terms of implementation I don't have too many issues however @He-Pin if you have time it would be great to address @pjfanning 's outstanding issues.

The MiMa changes definitely should go into a separate PR (which can be merged before this one at which point this PR should be rebased).

Also at the risk of bikeshedding, I would prefer if the resets-throttle-cost config was changed to reset-throttle-cost (i.e. de-pluralize the resets). To me as an english speaker "resets" sounds slightly off. This is however not a deal breaker from my side.

project/MiMa.scala Outdated Show resolved Hide resolved
@pjfanning pjfanning mentioned this pull request Dec 8, 2023
@pjfanning pjfanning marked this pull request as draft December 8, 2023 21:27
@pjfanning pjfanning changed the title HTTP/2 rapid reset mitigation [DRAFT] HTTP/2 rapid reset mitigation Dec 8, 2023
author PJ Fanning <[email protected]> 1698583210 +0000
committer PJ Fanning <[email protected]> 1702470760 +0100

test for http2 rapid reset

Co-Authored-By: Johannes Rudolph <[email protected]>

Update Http2ServerSpec.scala

add throttle and config

Co-Authored-By: Johannes Rudolph <[email protected]>

revert code format change

Update Http2ServerSettings.scala

Update Http2ServerSpec.scala

rework test - still needs proper asserts

refactor tests

scalafmt

Create http2-rapid-reset-configs.backwards.excludes

refactor test

update test

add ability to disable throttle

Update Http2ServerDisableResetSpec.scala

use keepLeft after rapidResetMitigation

Update http2-rapid-reset-configs.backwards.excludes

uptake sbt-pekko-build

use updated plugin

refactor

sbt-pekko-build 0.1.0

rename configs

rename vars
@pjfanning pjfanning marked this pull request as ready for review December 13, 2023 13:50
@pjfanning pjfanning changed the title [DRAFT] HTTP/2 rapid reset mitigation HTTP/2 rapid reset mitigation Dec 13, 2023
@pjfanning
Copy link
Contributor Author

I think I've covered most if the review items

@pjfanning pjfanning marked this pull request as draft December 14, 2023 12:10
@pjfanning pjfanning changed the title HTTP/2 rapid reset mitigation [DRAFT] HTTP/2 rapid reset mitigation Dec 14, 2023
@pjfanning
Copy link
Contributor Author

pjfanning commented Dec 14, 2023

I've just noticed that this throttle breaks some of the microbenchmarks. I think the throttle might be applied to too many frame types.

Running sbt from the incubator-pekko-http dir and executing

http-bench-jmh/Jmh/run -i 3 -wi 3 -f1 -t1 org.apache.pekko.http.impl.engine.http2.H2ServerProcessingBenchmark.*

This will fail with the changes in this PR but runs ok without them. The new throttle is set to fail if there are too many frames. This benchmark does not test rapid resets directly - so it appears that the new throttle is affecting too many frame types.

@pjfanning
Copy link
Contributor Author

I have changed the cost function on the frame throttle to only throttle RST frames. It may be useful to also throttle some other frame types - possibly also:

  • Continuation Frames
  • GoAway Frames
  • WindowUpdate Frames?

* Update H2ClientServerBenchmark.scala

* don't throttle header frames

* only throttle reset frames

* rename params

* Update H2ClientServerBenchmark.scala

* Update Http2ServerDisableResetSpec.scala
@pjfanning pjfanning changed the title [DRAFT] HTTP/2 rapid reset mitigation HTTP/2 rapid reset mitigation Dec 20, 2023
@pjfanning pjfanning marked this pull request as ready for review December 20, 2023 00:27
@pjfanning
Copy link
Contributor Author

I changed the code so that the rapid reset check is disabled by default. Would it be possible to have this reviewed again?

In the benchmark, the check does not seem to affect performance.

@He-Pin
Copy link
Member

He-Pin commented Dec 20, 2023

I changed the code so that the rapid reset check is disabled by default. Would it be possible to have this reviewed again?

In the benchmark, the check does not seem to affect performance.

How about with a configuration?

@pjfanning
Copy link
Contributor Author

pjfanning commented Dec 20, 2023

These are the results of running the H2ClientServerBenchmark on my laptop (with the change in this PR, resetFrameThrottleInterval=0s means no throttle applied and is the default). As you may see there is a small impact on my laptop, 0s runs are a little faster than 1s runs.

[info] Benchmark                                       (minStrictEntitySize)  (requestbody)  (resetFrameThrottleInterval)  (responsetype)   Mode  Cnt      Score      Error  Units
[info] H2ClientServerBenchmark.benchRequestProcessing                      1          empty                            1s          strict  thrpt    5  34987.925 ±  911.714  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1          empty                            1s  closedelimited  thrpt    5  29428.729 ± 2196.091  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1          empty                            0s          strict  thrpt    5  36503.237 ± 2168.155  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1          empty                            0s  closedelimited  thrpt    5  31649.809 ± 1056.275  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1    singleframe                            1s          strict  thrpt    5  34068.047 ± 1009.244  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1    singleframe                            1s  closedelimited  thrpt    5  29889.829 ± 2166.454  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1    singleframe                            0s          strict  thrpt    5  35286.571 ± 2411.328  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1    singleframe                            0s  closedelimited  thrpt    5  29821.582 ± 2270.763  ops/s

@pjfanning
Copy link
Contributor Author

pjfanning commented Dec 20, 2023

without my PR changes (ie latest main branch code) - this seems to show that the PR changes don't appear to affect performance unless you enable the throttle (non-default setting)

[info] Benchmark                                       (minStrictEntitySize)  (requestbody)  (responsetype)   Mode  Cnt      Score      Error  Units
[info] H2ClientServerBenchmark.benchRequestProcessing                      1          empty          strict  thrpt    5  35597.887 ± 2219.899  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1          empty  closedelimited  thrpt    5  30468.592 ± 1722.882  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1    singleframe          strict  thrpt    5  34457.236 ± 2100.593  ops/s
[info] H2ClientServerBenchmark.benchRequestProcessing                      1    singleframe  closedelimited  thrpt    5  29022.231 ± 5096.366  ops/s

Copy link
Contributor

@mdedetrich mdedetrich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, would be good to get an approval from someone else.

}
}

protected /* To make ByteFlag warnings go away */ abstract class TestSetupWithoutHandshake {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment after protected doesn't seem elegant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code was moved from another class - I didn't write the original comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, Should we keep it orgin? If it's not necessary, I still hope to be able to modify it.

@pjfanning pjfanning modified the milestone: 1.0.0 Dec 28, 2023
@pjfanning pjfanning marked this pull request as draft January 2, 2024 21:25
@pjfanning
Copy link
Contributor Author

closing due to #394

@pjfanning pjfanning closed this Jan 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants