Autor zmiňuje, že nekorektní uživatelský vstup lze omezit použitím vhodných vstupních elementů, takže pak není třeba tolik negativních testů na vstupy.
Tyto elementy ovšem nezabraňují odeslání nekorektních dat na server, takže bych podobné poučky radši nezmiňoval, aby nepoučení vývojáři nežili ve falešném pocitu, že je o vše postaráno...
Zde jsem to asi napsal špatně pochopitelně. Měl jsem tím na mysli situaci, kdy např. počet piv ;-) (viz následující příspěvek od lobo) se zadává pomocí výběrového seznamu nebo posuvníku. A z něj jde na server vždy jen kladné celé číslo v definovaném rozsahu (takže "ještěrku" skutečně nejde zadat :-) ). Nebo se pro zadání data místo tří vstupních polí (den, měsíc a rok), kam by šlo opravdu napsak jakoukoliv blbost, použije specializovaná komponenta, která nedovolí použít špatný formát a dokonce ani neexistující datum. Jasně, můžeme si splést 3. a 4. leden 2019, ale nemůžeme zadat ani formátově vyhovující 30.2.2019.
Z tohoto pohledu nerozumím větě: "Tyto elementy ovšem nezabraňují odeslání nekorektních dat na server..."
Chtěl jsem tím říci, že záškodník může do http requestu libovolně zasahovat a měnit ho, tedy místo data prostě může poslat třeba "ještěrku" a tedy to ověření správnosti dat musí být (také) na serveru a tedy si to zaslouží negativní testy stejné jako kdyby se žádná chytrá komponenta na straně klienta nepoužila.
Děkuji za jasné vysvětlení. Z tohoto pohledu bych chtěl říci, že máte naprostou pravdu o potřebě negativních testů na serveru. Ovšem musím kajícně přiznat, že tento typ testování (nazval bych jej už bezpečnostním, protože vyžaduje kvalifikovaného útočníka) jsem ve svých pokusech vůbec neprováděl.
Ale rozhodně děkuji za dobrý námět k přemýšlení.
Určitě se o této problematice prosím alespoň zmiňte, protože první věc, která někoho napadne, bude vyzkoušet si SQL injection a podobné srandičky. Taky ne vždy je dobré web komponentám věřit, že všechno ohlídají a že budou fungovat u všech uživatelů stejně (například počet znaků - znamená to počet bajtů, počet znaků, co se stane v případě right-to-left jazyků, v případě použití IME atd.).
ony jsou to možná spíš reakce na titulek článku :-), i když těžko říct, jak chápat ty uvozovky. Obecně platí, že to, co je na klientovi, nemůžeme jako develové moc ovlivnit ani uhlídat, takže kontrola vstupu na webové části je fajn a důležitá (asi to spadá do functionality a usability), ale kontrola na straně serveru je stejně nutná, možná ještě víc.
Jedna věc totiž je, že klientovi něco nepojede, když zapíše nevalidní údaje a druhá věc leak dat nebo nějaká ještě horší akce na serveru. Ale tam je toho ještě mega víc než jen prostá kontrola vstupů, samozřejmě záleží na kontextu, právech, skupinách, možná i na analyzované historii chování uživatele (to ale asi dělá málokdo, i když bych to uvítal) a ... je toho prostě moc...
Uvozovky u "pořádně" otestovat mají právě význam relativizace. Otestovat něco stoprocentně podle všech dimenzí kvality je nadlidský úkol. Já si ani netroufám říci, že jsem to _pořádně_ (tj. bez relativizujících uvozovek) otestoval funkcionálně. Přesto ten počet potřebných testů byl pro mne značným překvapením.
Bezpečnostní testování lze provádět i automaticky, jmenuje se to fuzz testing: https://en.wikipedia.org/wiki/Fuzzing.
A existuje na to spousta toolů jak pro konkrétní programovací jazyky (např. https://llvm.org/docs/LibFuzzer.html), tak i univerzální (http://lcamtuf.coredump.cx/afl/).
Kvalifikovaného útočníka to až tak nevyžaduje, protože existuje i spousta podobných toolů pro automatické útočení :).
jj fuzz testing je hodně zajímavej, hlavně ve chvíli, kdy se už začínáme tvářit, že je dotestováno a všechno vypadá v pohodě :-)
Právě si s tím hraju u našich REST API služeb (mám vlastní fuzzer, protože pro Python jsem nic pěkného nenašel) a je až neuvěřitelné, což všechno jsou ty služby schopné zkousnout za vstup :-) Samozřejmě to většinou zhavaruje někde dál, protože si to odchytne DB apod., ale někdy se podařilo zcela nesmyslná data "prohodit" právě až do databáze (grafové a dokumentové bez pořádného schématu)
Dobře, určitě se o tom dá napsat (doufejme že zajímavý) článek. Asi bych zmínil klasiku http://lcamtuf.coredump.cx/afl/ a asi zmínil ty REST API testy, protože s tím se asi setká hodně vývojářů Díky za tip!
Inu, toto mne opravdu zarazi. Autor pise o testovani WEBovych aplikaci a pri tom pise, ze je mozne omezit vstupy pouzitim spravne komponenty na klientu. Proboha, to je opravdu o webovych aplikacich? Toto ucite sve studenty?
Neni to zadny namet k premysleni. To je naprosty elementarni zaklad, ktery dneska musi znat kazdy student!!! Programator musi oddelovat weboveho klienta a serverovou cast. Nikdy se nesmi nikdo spolehat na data z weboveho klienta. Zarazi mne takto skolacka chyba u pana Herouta.
pred lety jsem pracoval v projektu, kde bylo mnoho rozhranni a subsystemu a pres ta rozhrani se posilala data. Jeden kolega, matematik prosadil presne to same co rikate, kazdy transfer dat byl neustale a znova verifikovan, jedno pres kolik to slo rozhrani.
To vse je sice teoreticky tak 'spravne', ale projekt zkrachoval, protoze zakaznik nebyl ochoten platit ty vicenaklady - pri navrhu toho software u toho ten matematik totiz jeste nebyl. Pamatuji si na ty diskuze jako dnes, jak se argumentovalo, ze jak prijdou data k sevru, tak je to treba zkontrolovat, protoze kdo vi, co se cestou zmenilo. :-)
Abych byl uprimny, s lidmi jako vy zasadne nepracuji, protoze ja rad zadanou praci dokoncuji v terminu.
Alespoň nějaká kontrola na serveru by proběhnout měla.
Já to řeším tak, že u klienta je podrobná kontrola s hezkým výpisem, co je zadané špatně a jak by to mělo být správně.
Na serveru je pak její zhuštěná verze, která při nekorektním vstupu jen vrátí odpověď, že data jsou chybná (žádné detailní pitvání, protože někdo nejspíš jen odeslal data nekorektním způsobem).
takze na tom servru ta data zkontrolujete, a kdyz bude vse vporadku, tak treba cast tech dat ulozite do DB a nejaka data poslete dal. Treba k nejakemu dalsimu servru. A tam ta data samozrejme zkontrolujete, protoze by se mohlo stat, ze se cestou neco zmenilo. A tak dale, a tak dale.
Ze zkusenosti vim, ze nakonec dojdete do situace, kdy se rozhodnete tem datum proste verit. A nebude to vubec nic neprofesionalniho nebo hloupeho. Uvedomite si, ze v urcitych situacich je ta pravdepodobnost, ze se v tech jednotlivych fazich zpracovani muze neco zmenit tak miziva, ze budete ta data povazovat za spravna -> proste se spolehnete na ty predchozi kontroly.
Autor clanku nikde presne nespecifikoval, jak bude jeho aplikace vypadat. Treba bude pouzivat komponenty, ktere jsou tak chytre udelane, ze bude jen s velkou namahou mozne ta data nejakym zpusobem modifikovat. (ten priklad s tim vyvojarskym panelem v browseru). Pak je mozno na servru povazovat ta data za validni, protoze to uz nekdo zkontroloval.
Samozrejme je ten vas postup rozumny a ja netvrdim, ze kontrola dat na servru je nesmysl a ztrata casu. Vadi mi ovsem, kdyz nekdo pronasi ty vyse uvedene 'absolutni' pravdy, ze kontrolovat je potreba !VZDY!
Vstupy je třeba kontrolovat !VŽDY!, když přichází z nedůvěryhodného zdroje - třeba když je tam cvaká člověk. Smysl nemá (nemusí mít) kontrola na každém důvěryhodném článku řetězce: když posílám zkontrolovaná data ze serveru na server a to zabezpečeným kanálem, má smysl jim věřit, protože už jednou zkontrolována byla.
Cokoliv z prohlížeče/electronu je třeba považovat za nedůvěryhodné a na serveru to zkontrolovat a případně nepustit dál, právě proto, aby takové požadavky nemohly nakazit ty části systému, které kontroly neprovádí. Nemusí to být žádná krása: "chyba v poli X - končím".
"Treba bude pouzivat komponenty, ktere jsou tak chytre udelane, ze bude jen s velkou namahou mozne ta data nejakym zpusobem modifikovat. (ten priklad s tim vyvojarskym panelem v browseru). Pak je mozno na servru povazovat ta data za validni, protoze to uz nekdo zkontroloval."
To může přijít těžké leda tobě.
Ve skutečnosti je svět plný lidí, co ti tam toho Bobbyho Tablese pošlou.
@honza
Jasně že je potřeba kontrlolovat vždy. Minimálně vůči uřité technologii, která má něco někam posunout odněkud někam. V tvém příkladu, když tedy obecném tak tedy obecně, zkotroluješ na frontendu to co zajímá uživatele (např. věk musí být int), zkontroluješ různé další druhy chyb a ůtoků na frontend, odešleš např. json na server a tam zkontroluješ co to má obsahovat a jak to má vypadat, co máš uložit ošetříš pro uložení, co máš přeposlat ošetříš pro přeposlání. Ano, není to tak jednoduché jako to prostě někam vrazit, protože už to kontroloval někdo jiný někde jinde ...
Re: honza (neregistrovaný) ---.dip0.t-ipconnect.de
Máte pravdu. Ta hranice, kdy už datům věřím, ale není jedna. Pro každý údaj je jiná. Je dána spíš tím, kde ještě se dá něco ověřit. Takže třebas to, zda zákazník existuje, se dá ověřovat až do úplného konce pomocí integritních omezení. Zda je částka v nějakém intervalu se také dá, byť tohle se moc nedělá. Ale třebas zda zákazník má dostatečný kredit na danou transkci, to už ověřit nejde a tam se vskutku musíte spolehnout na to, že to ověřil někdo výš. Už proto, že vlastně vůbec nemáte tušení o tom, co účtujete - je to prodej, storno, vratka, dobití kreditu, vratka zálohy, kurzový rozdíl, nebo co to vlastně je? Podobně při zápisu do hlavní knihy - úplně na konci je něco, co zapisuje řádek do účetnictví. A tohle něco se musí spolehnout na to, že ten, kdo to zavolal, to zavolá i podruhé a udělá tak správně zápis do podvojného účetnictví.
Tady ale někteří diskutují budou nesouhlasit. Bude to záležet na tom, kde oni mají nakreslené čáry a co považují za jeden celek. Já vyrostl na třívrstvé architektuře. Takže od databáze čekám jen integritní omezení. Kontrolu smysluplnosti dat pak očekávám od aplikačního serveru. V takové architektuře máte pravdu - databázový server věří tomu, že aplikační server již vše zkontroloval. Databáze sama nezná logiku aplikace, takže většinu kontrol ani nemá jak provést.
Zda s tvrzením "některé kontroly se nedají provádět až do konce a proto se na konci velké části dat musí věřit" bude konkrétní člověk souhlasit pak záleží na tom, zda vidí jen hranici mezi "klient" a "aplikační server", nebo zda vidí těch hranic víc, například právě tu mezi RDBMS a aplikačním serverem. Ti, co hranici databáze - aplikační server nevidí, vám těžko přiznají, že na téhle hranici už řadě věcí prostě věřit musíte.
K tomu jedna důležitá, ale obvykle zcela přehlížená věc: pokud chci, aby databáze mohla věřit datům z aplikačního serveru, tak si musím být jistý tím, s kým si povídám. Takže v databázi několik uživatelů, každý s pořádným heslem a velmi přesně omezenými přístupovými právy. Aplikační server prostě nemá důvod mít práva vytvářet nebo rušit tabulky, do řady tabulek není ani důvod aby měl práva DELETE. Pokud se do databáze hrabe více aplikací, tak každá má vlastního uživatele a vlastní práva. Docházka nemá co hrabat do kusovníků nebo si číst v účetnictví. Pokud chci mít jo jistotu, tak postavím čtvrtou vrstvu z vložených procedur přímo v databázi, která mi aspoň ty nejdůležitější věci typu změny hesla nebo plánování úloh ohlídá. Porovnejte to s typickou MySQL + PHP aplikací, kde je jediný uživatel, který má právo na úplně cokoliv.
Ja zase zasadne nepracuji s lidmi vaseho typu. Je krasne mit super komponenty v javascriptu, ktere uzivateli nedovoli zadat nevalidni data, ale vtip je v tom, ze zdrojem dat nemusi vubec byt webovy js klient. Muze to byt curl bot, api klient, hacker s telnetem, atd. To je uplne jedno. Funkcni backendovy celek proste musi resit validace svych vstupu. Spravny pristup je publikovat webove sluzby a pak je vam lhostejno, jestli k nim pristupuje webovy js klient, api klient, atd. O vice naklady se zpravidla nejedna. Naopak prinosem je lepsi skalovatelnost, testovatelnost a moznost prave vice klientu: zakaznicke api, webovy klient, mobilni aplikace, atd.