Autor Zpráva
Martin42
Profil *
Ahoj, mám stránky, kde tahám s databáze uložené informace (žádná hesla, žádní uživatelé).

Můj script není v žádném případě žádný zázrak, postupně jej vylepšuji a modifikuji, a přidávám nové funkce, když se něco užitečného naučim :) Ale o zabezpečení se mluvit určitě nedá. Všechna data se vypíšou do stránek, nic není tajného.

Do databáze se script přihlašuje jako užiivatel s omezenými právy (nemůže vytvářet ani nic mazat).

IMHO se mi nemůže nic stát, a nabourat se do toho přes php nebo mysql nejde, ale chci se jen ujistit.. mám pravdu?
krátké shrnutí: přihlašování do databáze jako uživatel s omezenými právy, nikde žádná hesla, ani nic tajného
peta
Profil
Nemas pravdu. MySQL injection se vetsinou tyka chybneho php kodu, kde uzivatel muze vlozit misto spravneho udaje sql prikaz napriklad:
$id = "1 OR 1=1 --";
$psw = "123";
$dotaz = "SELECT * FROM uzivatele WHERE id=$id AND password='$psw'"
Vysledny dotaz je SELECT * FROM uzivatele WHERE id=1 OR 1=1 -- AND password='123'.
Pokud znas boolenovu algebru, tak se podminka da prepsat jako WHERE 1=1, -- je znak pro komentar do konce radku. Cely dotaz by pak byl:
SELECT * FROM uzivatele
Coz urcite nechces uzivateli posilat celou tabulku uzivatelu :)

taham Z databaze
IMHO neni ceske slovo
Martin42
Profil *
Díky
Nejsem v tom příliš zběhlý (zatím :)

Ale, upřesním:
konkrétně mám:
SELECT * FROM Table WHERE `id` = '$id'
(tento způsob je víceméně používán všude, žádné jiné složitější dotazy do databáze nepoužívám, jen to s PHP dál zprácovávám + připojení je jen jako uživatel s omezenými právy)

id je získáno z adresy kterou volám..

Nechápu jak může někdo dát SQL dotaz do adresy a on se provede.

Podle mně at kdokoliv zadá do adresy cokoliv, tak to bude vždy bráno jako ID a pakliže nebude existovat nemělo by se nic stát. Je to tak?
Medvídek
Profil
Martin42:
Není, pokud ti do ID zadám co psal peta: 1 OR 1=1, tak se ti vykoná takovýto dotaz:

SELECT * FROM Table WHERE `id` = 1 OR 1=1 čili se podmínka splní vždy.
Takže u číselných hodnot vždy používej intval() a u textových mysql_real_escape_string(), nebo přejdi na mysqli :)
Str4wberry
Profil
Pokud zadáš, co psal pet, tak z toho vznikne:
SELECT * FROM Table WHERE `id` = '1 OR 1=1'
To se rozhodně vždy nesplní. :–)
Martin42
Profil *
ok, díky intval() určitě přidám. :)
Medvídek
Profil
Str4wberry:
Pravdu máš, přehlídl jsem uvozovky :) Ale pokud by ID bylo INT, tak by to mohlo být bez uvozovek. Ale jako vysvětlení v čem spočívá nebezpečí dobrý :)
Str4wberry
Profil
Hlavně je důležité se podívat na nastavení magic_quotes_gpc. Pokud bude zapnuté, tak mysql_real_escape_string bude na škodu a vytvoří dvojí escapování. Při zapnutí bude tedy kód z [#3] bezpečný, jinak je nebezpečný.
Majkl578
Profil
Str4wberry:
Při zapnutí bude tedy kód z [#3] bezpečný
Nebude, mysql_real_escape_string escapuje víc znaků. Rozhodně by nikdo neměl spoléhat na zmíněnou ohavnost (magic_quotes_gpc). V PHP 5.3 deprecated, (za pár týdnů aktuálně) v 5.4 odstraněno.

Pokud bude zapnuté
Pokud bude zapnuté, má se vypnout příp. se nadbytečného escapování zbavit explicitně před ošetřením mysql_real_escape_string.

Nicméně pokud bude vypadat dotaz takto:
SELECT * FROM uzivatele WHERE id='$foo'
a jako $foo zvolíme:
$foo = "' OR '1' = '1";
vznikne nám další vždy pravdivý dotaz:
SELECT * FROM uzivatele WHERE id='' OR '1' = '1'
Kajman
Profil
Ale pokud v té db nejsou žádná zabezpečená data, tak to maximálně rozbije stránku.
Medvídek
Profil
Kajman:
No vesměs by ses na nějaký lajdácký aplikaci i mohl přihlásit, ne?

mysql>SELECT * FROM uzivatele WHERE id='' OR '1' = '1'
if(mysql_num_rows($q)!=0){
 $_SESSION["admin"]=1;
}

Tento zápis sem dokonce i někde viděl jako vzorovej pro přihlašování :)
Kajman
Profil
Medvídek:
Já jen upozorňoval, že v prvním příspěvku psal, že v db nemá nic navíc, nic za zabezpečením ani žádné uživatele. Těžko se přihlásíš jako admin na stránkách, kde přihlašování není.
Str4wberry
Profil
Reakce na Majkla578:
Nebude, mysql_real_escape_string escapuje víc znaků.
Jak je, prosím tě, nebezpečný kód z [#3] s ohledem na SQL injection při zapnutí magic_quotes_gpc?

Nicméně pokud bude vypadat dotaz takto:
Tak při zapnutí magic_quotes_gpc vznikne:
SELECT * FROM uzivatele WHERE id='\' OR \'1\' = \'1'


Reakce na Kajmana:
tak to maximálně rozbije stránku
Když tam někdo připíše DELETE FROM uzivatele, tak to udělá ještě něco víc, ne? :–)

↑ Aha.
Alphard
Profil
Str4wberry:
Když tam někdo připíše DELETE FROM uzivatele, tak to udělá ještě něco víc, ne? :–)

Martin42:
Do databáze se script přihlašuje jako užiivatel s omezenými právy (nemůže vytvářet ani nic mazat).

Tohle je dokonalá případová studie :-)
Str4wberry
Profil
Tak já vycházel z toho, že konkrétní dotaz už je vyřešen a pokračujeme v obecné rovině. A [#12] Kajman jsem nějak přehlédl. Co se dá dělat, no. :–)
Majkl578
Profil
Str4wberry:
Jak je, prosím tě, nebezpečný kód z [#3] s ohledem na SQL injection při zapnutí magic_quotes_gpc?
Teď přemýšlím, jestli je rok 2012 nebo 2007. To sice nejspíš není, ale opravdu nemáš problém stavět script na magic_quotes? Jednou pak přijde update PHP a magic_quotes najednou zmizí, script bude najednou děravý a nikdo si toho nevšimne.
Ty ale asi narážíš na tu část „má se vypnout příp. se nadbytečného escapování zbavit explicitně“ - to proto, že s tím pak jsou i další problémy, např. při zpracovávání/vypisování dat (nadbytečné escapování) atd. Ale to snad nemusíme rozebírat.
(Tohle téma by možná spíš pasovalo do sekce PHP.)
Str4wberry
Profil
Ne, na nic nenarážím. Šlo mi o to, že uvedený kód považuji při magic_quotes_gpc za bezpečný proti SQL injection. A dost mě překvapilo, že ti bezpečný nepřijde, tak mě zajímalo, kde v něm vidíš riziko.

Zda spoléhat na magic_quotes_gpc či ne, o tom jsem tu nikde nepsal.
Majkl578
Profil
Str4wberry:
A dost mě překvapilo, že ti bezpečný nepřijde
Zohlednil jsem právě to, že magic_quotes jsou deprecated/removed a nelze na to spoléhat, čímž je to (potencionální) riziko.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: