Commit 86ce1dc
authored
Merge pull request from GHSA-jchv-x857-q8fq
* Forbid excessive sending of empty DATA frames
Motivation:
One vector for DoS can be sending a large number of essentially "empty"
frames, such as empty DATA frames without END_STREAM set. We should
forbid peers from doing so excessively, but we want to tolerate
implementations that occasionally emit such a frame for buggy reasons.
Modifications:
- Added verification that too many empty DATA frames are not sent.
Result:
Better resistance to DoS attacks.
* Improved buffering in CompoundOutboundBuffer
Motivation:
In HTTP/2 it is possible for remote peers to submit work in a way that
cause the NIOHTTP2Handler to generate a substantial number of control
frames. If the peer is not consuming these frames, we can eventually run
out of memory and die, which is not exactly ideal.
It's hard for us to know how the buffering is going if we always submit
all frames directly to the Channel, so we need to pay attention to
whether the Channel is actually writable. If it isn't, rather than issue
further writes we need to delay those writes so we can keep track of how
big that buffer is getting. If the buffer gets too large we need a
circuit breaker to drop the connection, as we're clearly not able to get
work done.
This patch adds a new buffer for outbound control frames. This new
buffer is the last step in the buffering sequence, and the first to be
drained when a Channel becomes writable.
Additionally, enhancements need to be made to ensure that other buffers
behave correctly in the face of this new model. The
ConcurrentStreamsBuffer needs to be more aggressive about storing
HEADERS frames that cannot be emitted to the wire because it does not
tolerate emitting a HEADERS frame that cannot be immediately written to
the wire. Additionally, the buffers must not be polled when a Channel is
unwritable.
This is a large patch, but it does substantially change the buffering
logic, and protects NIO against a wide range of denial of service
attacks, while providing a clear and coherent defense surface.
Note that one thing this patch does not do is constrain the size of the
buffers in the ConcurrentStreamsBuffer. This is on purpose: the size of
this buffer is controlled entirely by user action. Users that do not
wish to buffer excessively in this buffer can avoid doing so simply by
respecting the peer's value of SETTINGS_MAX_CONCURRENT_STREAMS. As the
entire purpose of this buffer is to tolerate users that do not wish to
abide by this setting, it would be unreasonable to provide an upper
bound on the value used in this setting.
Modifications:
- Moved the various buffers into a directory.
- Built and implemented ControlFrameBuffer.
- Integrated ControlFrameBuffer into CompoundOutboundBuffer.
- Added awareness around channel writability to HTTP2Handler
- Enhanced ConcurrentStreamsBuffer to be writability-aware.
Result:
We'll have somewhere to put control frames.
* Cleanup API for merged security fixes.
Motivation:
After merging the security fixes we ended up with a slightly awkward
API: the argument names differed slightly for no good reason, and it
became impossible to override only one of the two security settings.
Modifications:
- Renamed `max` to `maximum`.
- Gave default values for the security settings.
Result:
Better user experience.
* Prevent DoS with large header lists.
Motivation:
There are two ways malicious peers could attempt to DoS a SwiftNIO
HTTP/2 implementation with header lists. The first would be to attempt
to send an enormous header list, ideally with an amplification factor.
This approach was possible because SwiftNIO never actually enforced the
value of the max header list size it advertised.
In principle the peer can still get a good amplification attack effect
by sending a long header list that contains zero-length headers. We may
as well close this door as well: zero length header field names are
unacceptable, and so we should forbid them.
Modifications:
- Added max header list enforcement.
- Forbade zero-length header field names.
Result:
Peers cannot DoS a SwiftNIO HTTP/2 implementation using large header
lists.1 parent 492a77b commit 86ce1dc
File tree
27 files changed
+1292
-160
lines changed- Sources
- NIOHPACK
- NIOHTTP2
- ConnectionStateMachine
- Frame Buffers
- Tests
- NIOHPACKTests
- NIOHTTP2Tests
27 files changed
+1292
-160
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
32 | 40 | | |
33 | 41 | | |
34 | 42 | | |
| |||
43 | 51 | | |
44 | 52 | | |
45 | 53 | | |
46 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
47 | 58 | | |
48 | 59 | | |
49 | 60 | | |
| |||
73 | 84 | | |
74 | 85 | | |
75 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
76 | 96 | | |
| 97 | + | |
77 | 98 | | |
78 | 99 | | |
79 | 100 | | |
| |||
91 | 112 | | |
92 | 113 | | |
93 | 114 | | |
| 115 | + | |
| 116 | + | |
94 | 117 | | |
95 | 118 | | |
96 | 119 | | |
| |||
104 | 127 | | |
105 | 128 | | |
106 | 129 | | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
107 | 135 | | |
108 | 136 | | |
109 | 137 | | |
| |||
191 | 219 | | |
192 | 220 | | |
193 | 221 | | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
194 | 226 | | |
195 | 227 | | |
196 | 228 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
110 | 121 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
280 | 280 | | |
281 | 281 | | |
282 | 282 | | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
283 | 297 | | |
284 | 298 | | |
285 | 299 | | |
| |||
Lines changed: 3 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
Lines changed: 24 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
109 | | - | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
110 | 111 | | |
111 | 112 | | |
112 | 113 | | |
| |||
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
| 123 | + | |
| 124 | + | |
122 | 125 | | |
123 | 126 | | |
124 | 127 | | |
125 | 128 | | |
126 | 129 | | |
127 | 130 | | |
128 | 131 | | |
| 132 | + | |
129 | 133 | | |
130 | | - | |
| 134 | + | |
| 135 | + | |
131 | 136 | | |
132 | 137 | | |
133 | 138 | | |
134 | 139 | | |
135 | 140 | | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
141 | 146 | | |
142 | 147 | | |
143 | 148 | | |
144 | 149 | | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
145 | 161 | | |
146 | 162 | | |
147 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
143 | 143 | | |
144 | 144 | | |
145 | 145 | | |
| 146 | + | |
146 | 147 | | |
147 | 148 | | |
148 | 149 | | |
| |||
0 commit comments