"Díky explicitnímu rušení požadavků totiž útočník nikdy nepřekročí limit počtu současně otevřených proudů."
Moc tomu nerozumím. Nevidím do implementaci, ale pokud já jsem server a obdržím požadavek na zrušení, tak pokud je požadavek pending, neměl bych ho přece vyřadit ze seznamu alokovaných proudů a dál ho počítat do limitu. Je fakt, že pak je to nedeterministické, protože klient se nikdy nedozví, kdy se zrušený request skutečně stane zrušeným (přejde z pending do finálního stavu) a alokace jednoho proudu se uvolní. Ale to je snad jeho problém.
Přijde mi to trochu jako že protokol je obětí feature bloating. Přemýšlím, k čemu tahle featura vlastně je.
Pokud bych 1 stream 1 TCP spojení, tak i když odešlu požadavek a pak spojení zavřu, pořád mi ho server eviduje, dokud on ho sám nezavře na své straně. Pokud tam má aplikaci limitu počet TCP spojení na IP adresu, tak by se tohle polozavřené spojení počítalo do limitu.
Pokud HTTP/2.0 řeší jen slučování TCP spojení do jednoho, pak tohle je feature bloat.
Ok, tak možná jsem si to trochu rychle nastudoval.
Ten DoS se bude týkat konkrétní implementace. Tak předpokládá, že existuje nějaký centrální alokátor prostředků, který prostě neřeší, odkud žádost přišla. Pokud tedy klient rozjedná 100 žádostí a pak spojení zruší, zahltí tento centrální alokátor, a pokud to dělá dokola, nedostane se na běžné klienty a máme ty DoS.
Trochu vidím problém ve výkladu - významu maximálního množství proudů na spojení. To je - jak chápu - hard limit, tedy klient nesmí jít přes. Ale nikdo mě jako serveru nebrání omezit klienta i na menší počet streamů, třeba na 10, pokud to udělám snížením propustnosti. Tedy pokud má klient pending 10 požadavků, tak já mu ostatní strčím do fronty a to bez ohledu na to, jestli jsou pending a byly zrušeny. Tedy pokud klient zruší celý stream a znovu pošle 100 požadavků. měl by se strčit do jeho fronty.
Ten DoS bude tedy fungovat jen pokud server má globální frontu. Tam skutečně může útočník frontu zahltit.
Také mi to připadá jako problém konkrétní implementace. Protože to limitování počtu souběžných požadavků musí být implementované na každé straně, která se tak chce chránit. Takže server si musí hlídat, že klient nechce otevřít 101. stream, stejně tak si musí klient hlídat, že server nechce otevřít 101. stream. To, že proti strana ten limit zná a nebude se pokoušet otevřít stream nad limit je jen vylepšení, které umožňuje lépe fungovat hodným klientům a serverům, ale nebrání to útočníkovi.
No a když je počítání streamů navázaných klientem na serveru, je na serveru, jestli sníží počítadlo aktivních streamů hned, jak dostane požadavek na reset, a nebo jestli ho sníží až v okamžiku, kdy ten stream opravdu uzavře a nemá s ním žádnou práci. Může pak klientovi odmítat nové streamy, i když je klient pod limitem, ale to by měl klient ustát.
Proč je to feature bloat? Omezit počet souběžně běžících streamů je přece logické. Stejně tak se omezuje počet souběžných TCP spojení.