Problémy na Zdrojak.cz rubrika: Folklór

4 JanMurarik
položil/-a 22.7.2014

Koukal jsem, že na Zdrojáku to zase vře:

http://www.zdrojak.cz/clanky/sql-injection-pre-kazdeho/?show=comments#co...
http://forum.root.cz/index.php?topic=9430.0

Zajímalo by mě, co si o tom myslí Michal Illich a jestli vůbec ví, co tam Martin Hassman vyvádí.

Možná by neškodilo, kdyby články před vydáním někdo četl (když je čas na bedlivé "moderování" každého komentáře, tak se snad najde čas i na tohle, ne?).

odkaz
12 Kit
odpověděl/-a 22.7.2014

Komentáře jsem jen zběžně přehlédl. Asi nemá smysl je číst.

Článek ukazuje pár útoků s mizerným závěrem. Escapování snad už nikdo nedělá, prepared statements to jistí.

ORM nepoužívám, SQL dotazy píši ručně a nestydím se za to.

Komentáře

  • JanMurarik : To snad není za co se stydět. SQL bylo navržené, aby ho mohli psát dokonce uživatelé. 22.7.2014
  • spazef0rze : Kromě těch, co escapují nebo používají prepared statements jsou tu i tací, kteří neescapují a nepoužívají ani prepared statements. První dvě skupiny jsou poměrně velké, ale ta třetí je také nezanedbatelná, ostatně na tu Igor ukazuje v tom článku. 27.7.2014
  • David Grudl : Mohl bys mi ukázat, jak pomocí prepared statements třeba v PDO vytvoříš dotaz `SELECT a FROM b WHERE c IN (...)`? 5.8.2014
  • Kit : Blbě napsané dotazy se do prepared statements přepisují také blbě. 6.8.2014
  • JanMurarik : David Grudl: Do závorky vložíš patřičný počet otazníků a následně dotaz parametrizuješ. Vkládáním otazníků a čárek na předem určené místo není možné ten dotaz rozbít, nelze tam zanést SQL injection a nemůžou tam prosáknout data od uživatele/útočníka (vstup ovlivňuje jen počet otazníků a čárek). Samozřejmě to ztrácí výhodu opakovaného použití připravených dotazů (pokud se liší počty parametrů), ale výhoda bezpečnosti zůstává. Toto opravdu není důvod pro escapování (natož sanitizaci) a lepení SQL z textů, které přišly od uživatele. 6.8.2014
  • Kit : @JanMurarik: Ano, to je způsob, kterým jsem to kdysi řešil, Lepení SQL dotazů se mi však vůbec nelíbí. Vždyť kdo z nás takhle slepuje PHP skripty za běhu? Snad nikdo. 6.8.2014
  • David Grudl : Kit: tak buď ukaž, jak zapíšeš IN (...) bez lepení, nebo uveď argument, proč je dotaz používající IN blbě napsaným. 10.8.2014
  • Kit : Uložím data do dočasné tabulky. Stejně je tam zpravidla už mám. Případně použiji select z jiné tabulky a tím jeden dotaz ušetřím. 10.8.2014
  • David Grudl : Takže v jednu chvíli může probíhat jen jeden dotaz. Hmm, originální řešení. 11.8.2014
  • vaclav.sir : Pokud jde o PHP+MySQL, tak temporary tabulky jsou vázané na session a v PHP je obvyklé mít pro každé vlákno vlastní spojení s DB, takže problém s konkurencí tam není. Spíš by mě zajímalo tohle: Uživatel zaškrtne N kategorií k výběru, tobě tedy přijde pole s IDčkama, jak ho nasypeš do té temporary tabulky? Jeden insert pro každé ID (pomalejší), nebo jeden insert pro všechny (lepení SQL)? 11.8.2014
  • Kit : V tomhle případě nepoužiji dočasnou, ale permanentní tabulku, aby mi výběr zůstal zachován i po přechodu mezi stránkami. S lepeným SQL by se blbě dělala validace vstupních dat. 11.8.2014
  • Žížala : Ad klausule IN: http://php.net/manual/en/pdostatement.execute.php#example-994 . A řešení přes dočasnou/pernamentní tabulku považuji za zvěrstvo. Musíš udělat minimálně jeden INSERT navíc. A proč by se s lepeným SQL měla dělat špatně validace dat? 11.8.2014
  • Kit : Protože validační pravidla se z db blbě vytahují. Je lepší je použít přímo tam během insertu. 11.8.2014
  • Žížala : Ty nemáš 1:1 datový model v aplikaci a DB??? 11.8.2014
  • siq : Kit ma svoj metajazyk, ktory to urcite riesi za neho, takze ORM vobec nepotrebuje. 11.8.2014
  • kohven : @vaclav.sir: Výhodné je to s ajaxem. Tabulka se plní idčkama už když je uživatel vybírá a výsledný dotaz se pak jen joinuje na tabulku s IDs. Celkově sice větší zátěž, ale částečně rozložená i do doby, kdy se čeká na uživatele. A když je hodně položek, tak už se může projevit i rychlost "join" před pomalejším "in (...)". Další benefity byly už zmíněny - snazší validace a možnost pamatovat si naposledy vyplněné hodnoty. Ale zase je větší traffic. Každopádně vždycky záleží na okolnostech, co od toho chci a co si můžu dovolit. 11.8.2014
  • Kit : @Žížala: Ne. Proč bych měl dělat cache v objektech? Ještě by se mi ušpinila, nemluvě o zvýšeném riziku souběhu. Také bych musel dělat validaci vstupu pro každého klienta zvlášť . U některých to ani nejde. 11.8.2014
  • Kit : @kohven: Přesně tak. Navíc to funguje i při přístupu z více klientů současně. 11.8.2014
  • siq : Nechapem, na co sa pri niecom takomto takto skrabat cez hlavu. Ked to robim s in(...), tak to mam napisane mnohonasobne rychlejsie, nez to agregovat cez nejake dalsie tabulky. Selectnute ID si drzim v session. Kde je problem? Naco si to zbytocne komplikovat? 11.8.2014
  • Kit : Odkud bereš data do toho in(...)? Pokud od uživatele, měl bys je validovat. Session je velmi často v databázi. Proč konvertuješ db->session->db? Není to zbytečná režie? 11.8.2014
  • siq : Ok, session je velmi casto v databazi, ale castejsie je na file systeme, casto je aj in memory(memcached). Navyse aj keby to bolo v DB, tak je ten jeden round trip do DB zanedbatelny. Z mojho pohladu je to len zbytocne pridavanie komplexnosti. Toto je podla mna dost overengineering. 11.8.2014
  • Kit : Objetový přístup je podle mne přesouvání operací co nejblíže k datům, kterých se týkají. Proto k nim přesouvám i dočasná data. Vždyť dočasné tabulky MySQL se také přednostně ukládají do RAM. 11.8.2014
  • siq : To je ale dost autisticky sposob pozerania na problem. Ja to nakodim rychlejsie a jednoduchsie. Tym ze je to jednoduchsie, je aj mensia sanca, ze sa tam vyskytne chyba. Dalej ma podla mna tvoj kod nizsiu transparentnost, nez ked je to naprogramovane "polopatisticky". Horsie sa budu debugovat pripadne problemy, ktore sa vyskytuju len v produkcii(ah, takze ta temp tabulka je viazana na pripojenie, a to je viazane na SESSION, parada!). Ja by som k takemuto rieseniu pristupil, len ak by ma k nemu nieco prinutilo, inak je to zbytocna praca a problemy navyse len za to, aby som mal papierovo cisty objektovy dizajn. 11.8.2014
  • Žížala : siq : +1000 11.8.2014
  • Taco : Moc vám nerozumí, o co se přetahujete. Zatím bych z tohoto vlákna zdůraznil: "Odkud bereš data do toho in(...)? Pokud od uživatele, měl bys je validovat." 11.8.2014
  • vaclav.sir : Ne vždy je nutné validovat, někdy stačí sanitizovat. 11.8.2014
  • Kit : Výhodou mého řešení je, že to lepení, validaci a sanitizaci nemusím dělat v každém klientovi a každém jazyku znovu. Stejně bych musel z db vytahovat validační pravidla, takže pracným programováním klientů bych nic neušetřil. 11.8.2014
  • Taco : @Kit: No, mě to šašení s temporary tabulkou přijde trochu moc. Ale i u mne platí, že se snažím, aby třeba id neopouštěla repository. 11.8.2014
  • Kit : @Taco: Neboj, temporary table ve skutečnosti nepoužívám, protože data jsou pro mne zajímavá i po zavření spojení s databází. Stejně jsem se dosud nedozvěděl, o lidi dávají do toho IN(...) kromě zaškrtávátek. Obávám se, že jen výsledky jiných SQL dotazů. 11.8.2014
  • pavel.stehule : V PostgreSQL se problém SELECT WHERE IN (seznam) a Prepared statement elegantně a bezpečně může řešit použitím pole a funkce string_to_array. Určitě je to výrazně rychlejší než temp table - ta má smysl až u několika seti parametrů. Vyžaduje to server side PP, ale je to neprůstřelné a jednoduché. 11.8.2014
  • kohven : @Kit: IN(...) používám kromě zaškrtávátek relativně často a dávám do toho cokoliv kromě ids, ale ne dynamicky. Tzn. nikde ho neskládám. Ale na to ses asi neptal. :) 11.8.2014

Pro zobrazení všech 3 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.