tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

Zákaz vkládání řetězců nebo alespoň ztížení

před 9 lety

David Grudl
Nette Core | 6806

Dibi je velmi bezpečný databázový layer, nicméně na vynalézavost některých programátorů nemá :-)

Občas narážím na podobný kód:

dibi::query("SELECT * FROM [table] WHERE name='$name'"); // namísto name=%s', $name);

Což samozřejmě nese riziko SQL injection. Uvažoval jsem, jak tomu zabránit. Jednou z možností by bylo zakázat jednoduché uvozovky a podporovat jen dvojité, protože na zápis name='" . $name . "' se narazí asi méně (ale možná se pletu). Případně použít úplně jiný znak.

Je mi jasné, že nejde jen tak přestat podporovat uvozovky. Buď by bylo možné je spojit s vyhozením E_WARNING, nebo přidat nějaký přepínač.

Co myslíte?

před 9 lety

westrem
Člen | 398

No toto bude asi dost zakrsly problem. Zober si pripad:

dibi::query("SELECT * FROM [table] WHERE [type] = 'new'");

Tzn. ked niekto z nejakeho dovodu (napr. menej parsovania) da do query staticky string. V tomto pripade riziko nehrozi a nepodporovanie uvodzoviek by malo za nasledok (asi) vratenie chyby o zlej query.

Skorej by som sa priklonil k vyhadzovaniu tomu E_USER_WARNING, ze pozor v tej query moze byt bezpecnostne riziko spolu s niecim ako „Mali ste namysli toto?“

protože na zápis name=‚" . $name . "‘ se narazí asi méně (ale možná se pletu)

Odpovedal si si sam, na vynaliezavost proste len tak hocikto nema .. verim tomu, ze aj takyto zapis moze byt u niekoho uplne bezny.

před 9 lety

muta
Člen | 21

no a co to kontrolovat na znak $ ten v mysql syntaxi neni. Timhle by mi to prislo nejbezpecnejsi. A jsem pro vyhazovani vyjimek :)

Petr

před 9 lety

paranoiq
Člen | 388

no a co to kontrolovat na znak $ ten v mysql syntaxi neni.

WTF? O_o . k dosazení proměnných dojde dřív než se ti řetězec dostane do ruky

Jednou z možností by bylo zakázat jednoduché uvozovky a podporovat jen dvojité, protože na zápis name='" . $name . "' se narazí asi méně

nechápu. tohle name='" . $name . "' a tohle name='$name' je přeci totéž

chtěl by jsi snad v rámci bezpečnosti zavést možnost pro tohle?:

$name = '"; DROP TABLE [users]; --';
dibi::query("SELECT * FROM [table] WHERE name=\"$name\"");

uživatelé i útočníci jsou vynalézaví. ať bude oddělovač řetězců v dibi query jakýkoliv, vždy jej bude možné překonat. jedinou možností je konstantní řetězce vůbec nepodporovat

a varování povede akorát tak k tomu, že si ho ti, kterým je nejvíce určeno, vypnou :[

před 9 lety

westrem
Člen | 398

muta napsal(a):

no a co to kontrolovat na znak $ ten v mysql syntaxi neni. Timhle by mi to prislo nejbezpecnejsi. A jsem pro vyhazovani vyjimek :)

Petr

Presne ako pise paranoiq, vyhodnotenie stringu sa predsa spravi skorej ako ho parser od dibi zacne spracovavat ;)

paranoig napsal

uživatelé i útočníci jsou vynalézaví. ať bude oddělovač řetězců v dibi query jakýkoliv, vždy jej bude možné překonat. jedinou možností je konstantní řetězce vůbec nepodporovat

Tiez som rozmyslal nad tym, ze napisem toto, ale nebol som si isty ci by to kompatibilne nemohlo robit nejake problemy. Ale myslim si, ze je to way to go, pretoze ak chce niekto raw retazce tak nech vyuziva ::nativeQuery a nie ::query.

a varování povede akorát tak k tomu, že si ho ti, kterým je nejvíce určeno, vypnou :[

To je mozne, ale v tom pripade je to uz nanajvys blbost a starost toho cloveka, nicmene viem si predstavit situaciu, ked niekto pise kod ako ukazal David:

dibi::query("SELECT * FROM [table] WHERE name='$name'"); // namísto name=%s', $name);

S tym, ze si mysli, ze ked pouziva „obalku“ dibi tak je chraneny no v skutocnosti ostal pri starom zapise SQLka a takto si tam tu bezp. dieru privolava sam. V tomto pripade by mu ten error pomohol a ukazal spravnu cestu, nemyslis?

před 9 lety

paranoiq
Člen | 388

dejme tomu, že by to vyhazovalo warning. při zápisu konstantního řetězce chybu jednoduše umlčím. šak vím co dělám, žé:

@dibi::query("SELECT * FROM [table] WHERE name='default'");

vše v pořádku.

za měsíc někdo udělá úpravu:

@dibi::query("SELECT * FROM [table] WHERE name='$name'");

zavináč přehlédne. a kde to jsme? :[

zakázat uvozovky a použít nativeQuery nelze. to by vedlo k ještě horším věcem. někteří by si na to zvykli a začali to běžně používat a ochrana proti SQLi by se naopak zhoršila

myslím, že celý tenhle problém nemá smysl vůbec řešit (jedině pořádným upozorněním v dokumentaci), protože spolehlivé řešení není a zakázání řetězců v query by bylo příliš radikální. pokud se někdo chce střelit do nohy, tak prosím…

před 9 lety

paranoiq
Člen | 388

možná by mělo smysl, aby dibi::query vyhodila výjimku, pokud dostane ke zpracování řetězec obsahující více než jeden dotaz – to může být jasným příznakem toho, že došlo k SQLi. detekce by nemusela být tak složitá, ale musela by se vzít v úvahu třeba změna delimiteru

vzhledem k tomu, že dibi nepodporuje vícenásobné resultsety, tak asi k pokládání více dotazů jedním voláním query příliš důvodů není. případně by se mohla přidat metoda multiQuery

před 9 lety

David Grudl
Nette Core | 6806

paranoiq napsal(a):

možná by mělo smysl, aby dibi::query vyhodila výjimku, pokud dostane ke zpracování řetězec obsahující více než jeden dotaz – to může být jasným příznakem toho, že došlo k SQLi. detekce by nemusela být tak složitá, ale musela by se vzít v úvahu třeba změna delimiteru

K výjimce obvykle dojde, protože snad kromě SQLite nikdo vícenásobné dotazy nepodporuje. Ale injection se netýká jen vícenásobných dotazů.