Autor Zpráva
mafos
Profil
Dobrý den,
chtěl bych vyřešit, aby se mi nemohla stát ona nepříjemnost zvaná SQL injection :-) Zatím se mi to však bohužel nedaří. Prošel jsem nějaká návody, ale nic. Nepodařilo se mi ani na vlastních stránkách zjistit jestli jsou OK nebo ne. Mohli byste se mi na to prosím mrknout a poradit mi jak předejít SQL injection a aby to fungovalo?
Kod ze stránek je zde
$link = mysql_connect ("localhost", "jméno", "heslo") or die ("Nepovedlo se připojit na databázový server");
$db = mysql_select_db("jméno", $link) or die ("Nepovedlo se otevřít databázi");
mysql_query("SET NAMES 'cp1250'") or die('Nepodařilo se nastavit jazyk'); 
$query = "SELECT * FROM clanky where id=$id";
$result = mysql_query($query, $link) or die("SQL dotaz nešlo provést");

A stránky jsou dostupné zde www.halva.org/tristudne. Kod který jsem poslal je použitý v www.halva.org/tristudne/clanek.php?id=
Díky za jakoukoliv radu.
Alphard
Profil
$query = "SELECT * FROM clanky where id= ". (int) $id;
Musíte ošetřovat uživatelské vstupy, když očekáváte číslo, zajistěte, aby to vážně bylo číslo. Na řetězce je potom funkce mysql_real_escape_string().

Ty or die za každým dotazem jsou možná trochu zbytečné. Uživatelé neradi vidí bílou stránku s textem, kterému nerozumí. Radši tam dejte normální podmínku, až zůstane známý design a jen vypište nějakou hlášku s radou, jak problém vyřešit.
Jan Tvrdík
Profil
Pro pohodlnou ochranu vůči SQL injection lze použit dibi či jinou šikovnou knihovnu.
mafos
Profil
Očekávám číslo, nic jiného. Změnil jsem to tedy, přidal jsem . (int) $id . Můžete mi na to prosím ještě mrknout jestli je to tedy teď OK a je zabráněno SQL injection? Jak říkám, ani vlastní stránky nedokážu nabořit :-) Změnil jsem to zatím pouze v jednom kodu a nahrál ho pro testovací účely na http://www.halva.org/tristudne/clanek2.php?id= .
Mnohokrát děkuji
123456789
Profil *
Ne to nestačí. Já ty stránky nabourám i teď, takže by ses měl snažit dál.
123456789
Profil *
Abys věděl, že nekecám, tak používáš mysql 5.0.51.
mafos
Profil
123456789:
Já ty stránky nabourám i teď
Podařilo se Ti je nabourat přes stránku clanek2.php? Ostatní jsem totiž ještě nijak neupravoval.

Mohli byste mi prosím ještě poradit jak to víc zabezpečit? Vůbec si s tím nevím rady :-(
Kod jsem upravil s int, víc nevím co udělat :-( Mám to zkusit předělat přes doporučované dibi?
$link = mysql_connect ("localhost", "jméno", "heslo") or die ("Nepovedlo se připojit na databázový server");
$db = mysql_select_db("jméno", $link) or die ("Nepovedlo se otevřít databázi");
mysql_query("SET NAMES 'cp1250'") or die('Nepodařilo se nastavit jazyk'); 
$query = "SELECT * FROM clanky where id= ". (int) $id;
$result = mysql_query($query, $link) or die("SQL dotaz nešlo provést");


Díky
mafos
Profil
Takže jsem zkoušel projít ještě nějaké návody na netu. Našel jsem tenhle návod. Zkusil jsem to podle něj předělat. Zdá se mi, že by to možná mohlo fungovat. Aspoň podle toho co říkají. Když zadám http://www.halva.org/tristudne/clanek2.php?id=20 tak je to OK když zadám http://www.halva.org/tristudne/clanek2.php?id=1%20and%201=1/* tak to vypíše chybu. Mohli byste mi prosím na to mrknout jestli už by to fakt bylo OK?
Kod vypadá takto:
$link = mysql_connect ("localhost", "jméno", "heslo") or die ("Nepovedlo se připojit na databázový server");
$db = mysql_select_db("jméno", $link) or die ("Nepovedlo se otevřít databázi");
mysql_query("SET NAMES 'cp1250'") or die('Nepodařilo se nastavit jazyk'); 

$id = $_GET["id"];  
//kontrola, zda je id cislo  
if (!is_numeric($id)):   
echo "Toto ne!";  
else:
$query = "SELECT * FROM clanky where id='$id'";
endif;


$result = mysql_query($query, $link) or die("SQL dotaz nešlo provést");

Děkuji
123456789
Profil *
No ja tento thread cetl jen velmi letmo, takze jsem zminku o tom, ze si zabezpecil jen jednu stranku prehledl. Pres kterou stranku jsem se tam dostal si nepamatuju.

Kazdopadne pokud chces zabezpecit stranky pred timto druhem utoku, tak se v prve rade nauc SQL. Pak take neco o PHP, pak si precti pak clanku o SQL injection, na par webech si ji vyzkousej (nenabadam te ovsem k tomu, abys neco nicil) a pak si zabezpeci svuj web. Prace tak na tyden.
Nox
Profil
To je podle mě úplně to stejné..... žádnou díru tam nevidim a kdoví jestli se to nějak 123456789 vůbec povedlo, protože nenapsal ani nic konkrétního, nebo šlo o tu neošetřenou stránku
mafos
Profil
Nox:
Předělal jsem to podle toho návodu jak jsem posílal, protože tam píšou, že ve chvíli kdy zadám id=1 and 1=1/* a vypíše to článek, tak útočník pozná, že je tam chyba. Tzn. tady je to s int http://www.halva.org/tristudne/clanek3.php?id=1%20and%201=1/* a vypíše to článek, tady je to podle programujte.com http://www.halva.org/tristudne/clanek2.php?id=1%20and%201=1/* a vypíše to chybu. Z toho jsem usoudil, že tak je to asi líp. Ale pokud je to teda stejný, tak předělat to na int je určitě rychlejší a líbí se mi víc :-)

123456789:
Předpokládám, že ses tam možná dostal přes formulář na registraci novinek, protože mi ráno přišlo upozornění na nového uživatele a byl tam kod, který jsi zadával. Ale to je jedno, hlavní je, že se Ti tam podařilo dostat. Stránky určitě chci zabezpečit. Myslíš, že teď už je to teda OK nebo ne? Mluvím pouze o odkazech, které jsem poslal. Zbytek stránek jsem zatím nijak neupravoval.
Nox
Profil
mafos:
Předělal jsem to podle toho návodu jak jsem posílal, protože tam píšou, že ve chvíli kdy zadám id=1 and 1=1/* a vypíše to článek, tak útočník pozná, že je tam chyba.
Není

string->int "The value is given by the initial portion of the string . If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero)."

tudíž se do query nedostane "1 and 1=1/*" ale "1", což vůbec nevadí => žádná chyba tam není.... co je tam napsaný kromě toho se prostě ignoruje

To už je pak na tobě, jak to chceš interpretovat, jestli vzít co jde a zbytek ignorovat, nebo zobrazit vždy hlášku.... každopádně takto útočník nikdy neprovede nic škodlivého, což je to o co jde primárně
mafos
Profil
Nox:
To už je pak na tobě, jak to chceš interpretovat, jestli vzít co jde a zbytek ignorovat, nebo zobrazit vždy hlášku
Vezmu co jde a zbytek budu ignorovat. Tzn. použiji zápis s int. Díky za rady. Myslím, že tím to snad bude vyřešené.
mafos
Profil
Ještě bych měl jeden dotaz ohledně SQL injection. Jedná se o stejné stránky. Přidávání e-mailů do databáze pro zasílání novinek řeším stránkou odkaz (viz. změna) . Tento odkaz přidá uživatele do databáze. Je to vlastně jediný skript, kde se neočekává číselná hodnota. Jak to zabezpečit? Šlo by to takto:
$link = mysql_connect ("localhost", "jméno", "heslo") or die ("Nepovedlo se připojit na databázový server");
$db = mysql_select_db("jméno", $link) or die ("Nepovedlo se otevřít databázi");
mysql_query("SET NAMES 'cp1250'") or die('Nepodařilo se nastavit jazyk');
$email = mysql_real_escape_string($_GET["email"]);  
$query = "INSERT INTO novinky (id, email)
	VALUES ('', '$email')";
$result = mysql_query($query, $link) or die("SQL dotaz nešlo provést");
mysql_close();

Je toto dostatečné?
Děkuji

změna - odstranil jsem odkaz na registraci do novinek z důvodu přidání několika prázdných e-mailů. Děkuji za pochopení.
123456789
Profil *
Přes formulář na registraci novinek jsem se tam nedostal. Byla to nějaká neošetřená stránka.
mafos
Profil
123456789
A formulář by už teď byl dobrý? Zbytek zabezpečuji přes int, pracuji na tom.
Kajman_
Profil *
Je toto dostatečné?
Ano stringy prohnané mysql_real_escape_string a dané do apostrofů jsou ošetřené.
mafos
Profil
Kajman:
Super, díkec všem.

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:

0