PHP: ochrana proti spamu a injekci MySQL

Jakub

PHP: ochrana proti spamu a injekci MySQL
« kdy: 10. 09. 2012, 12:15:11 »
Dobrý den,

mám takový jednoduchý formulář, kde od uživatelů dostávám citlivé údaje ....
Celý server proto "kryji" pomocí HTTPS...

Formulář pak jako bezpečnostní prvky používá mysql_real_escape_string proti injekci SQL a proti spamu funkci rand(),
pomocí které vytváří 3 náhodné otázky a do proměnných SESSION registruje odpovědi z důvodu, aby nebyli přímo uživateli dostupné.

Pokud je registrace dokončena a je adminem validována uživatel dostane přistup na web admin, kde má možnosti přístupu podle toho
jaké má proměnné v SESSION.

Co se týče samotných formulářů a jednotlivých sekcí kde je nutná autorizace, tak tam testuji zdal - li je SESSION přihlášená a všechny formuláře jsou ve složce s oprávněním 644.

Považujete tohle za dostatečné řešení ? Měl bych to udělat jinak ? Nebo něco doplnit pro navýšení bezpečnosti ?
 
« Poslední změna: 10. 09. 2012, 15:09:12 od Petr Krčmář »


Jakub

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #1 kdy: 10. 09. 2012, 12:26:00 »
Co se jinak ještě těch formulářů týče, tak obsahují skryté prvky jako "username" atd... které když jsou vyplněny tak se stane formulář neplatným.
Předávání dat mezi registrační stránkou a stránkou, která provádí kontrolu dat a odeslání dat je provedeno pomocí "post"

PJ

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #2 kdy: 10. 09. 2012, 13:44:03 »
Formulář pak jako bezpečnostní prvky používá mysql_real_escape_string proti injekci SQL a proti spamu funkci rand(),
pomocí které vytváří 3 náhodné otázky a do proměnných SESSION registruje odpovědi z důvodu, aby nebyli přímo uživateli dostupné.
mysql_real_escape_string() nevyriesi vsetko (to len ci si na to davate pozor) - napr.
Kód: [Vybrat]
$hodnota = mysql_real_escape_string($_POST['hodnota']);
$q = mysql_query("SELECT * FROM tabulka WHERE stlpec=$hodnota");

Pokud je registrace dokončena a je adminem validována uživatel dostane přistup na web admin,
Validacia dufam obsahuje nieco ako htmlspecialchars() alebo to mate osetrene niekde pri vstupe...

kde má možnosti přístupu podle toho jaké má proměnné v SESSION.

Co se týče samotných formulářů a jednotlivých sekcí kde je nutná autorizace, tak tam testuji zdal - li je SESSION přihlášená
Pozor na zdielane hostingy, tam je casto treba nastavit vlastnu cestu pomocou PHP funkcie session_save_path() alebo nastavenia session.save_path - inak je casto mozne, aby druhy uzivatel hostingu nastavil lubovolne session premenne.
Ale dufam, ze pri citlivych datach nejde o zdielany hosting.

a všechny formuláře jsou ve složce s oprávněním 644.
To vyzera na problem so zdielanym hostingom. Tam mozu byt aj ine problemy - bud amatersky hoster pusta vsetky skripty pod 1 uzivatelom alebo mu to niekto exploituje a 644 nepomoze. Aj u vacsich zdielanych hostingov som videl aj ine problemy, ktore umoznovali napriklad ziskat zdrojak lubovolneho PHP suboru, takze sa na ochranu nespoliehajte na 100%.

Předávání dat mezi registrační stránkou a stránkou, která provádí kontrolu dat a odeslání dat je provedeno pomocí "post"
Na POST nezalezi, ak to nie je skombinovane s niecim inym.

Jakub

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #3 kdy: 10. 09. 2012, 14:03:20 »
Máme vlastní server, kvůli odesílání informačních mailů...
Takže s oprávněním 644 by neměl být problém.
Cestou pro SESSIONS mám nastavenou i jejich platnost...


Co se týče:
Kód: [Vybrat]
$hodnota = mysql_real_escape_string($_POST['hodnota']);
$q = mysql_query("SELECT * FROM tabulka WHERE stlpec=$hodnota");

Tak já používám:
Kód: [Vybrat]
$hodnota = mysql_real_escape_string($_POST['hodnota']);
$q = mysql_query("SELECT * FROM tabulka WHERE stlpec='$hodnota'");


Je to chyba ?

K té validaci ...
Pokud se uživatel registruje MYSQL mu automaticky nastaví, že není jeho profil schválen, což může provést jenom uživatel,
který má v SESSION['admin']==true;




PJ

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #4 kdy: 10. 09. 2012, 14:33:19 »
Tak já používám:
Kód: [Vybrat]
$hodnota = mysql_real_escape_string($_POST['hodnota']);
$q = mysql_query("SELECT * FROM tabulka WHERE stlpec='$hodnota'");
V MySQL v default nastaveni to tak AFAIK vzdy funguje az na extremy ako stlpec s cislami typu VARCHAR a pouzitie nerovnosti. Mimo MySQL alebo pri inom nastaveni MySQL sa u stringov uvodzovky vyzaduju, ale u cisel s tym moze byt (vo vseobecnosti) problem.

K té validaci ...
Pokud se uživatel registruje MYSQL mu automaticky nastaví, že není jeho profil schválen, což může provést jenom uživatel,
který má v SESSION['admin']==true;
Tam bol skor problem s tym, ci zly uzivatel (neadmin) nemoze pri registracii zadat za meno nieco ako
Kód: [Vybrat]
<script>document.getElementById('schval').submit()</script>co by ho potvrdilo hned pri nacitani stranky adminom, keby sa neescapovali entity < a >.


Jakub

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #5 kdy: 10. 09. 2012, 14:46:59 »
Ta validace je dělána tak, že uživatel jako admin se přihlásí...
Vyhledá si v mysql prostřednictvím web console uživatele a schválí ho ...

Proces je následujicí:
Admin se přihlásí: je volán vyhledávání v mysql, kde pokud je shoda tak se nastaví SESSION['admin']=true jinak je false.
Pak se přepne na stránku s vyhledáváním uživatelů: Stránka ověří jestli je SESSION['login']=true a jestli je SESSION['admin'] true.
Pokud ano stránka se zobrazí.

Při příkazu vyhledávání se znovu SESSION ověří a při příkazu MYSQL SET ... se znovu před vykonáním příkazu ověří jestli je admin opravdu admin a jestli je stránka přihlášena....

Squirrel

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #6 kdy: 10. 09. 2012, 14:54:38 »
Little Tip: na mysql etc... existuje knihovna Dibi, ktera spoustu veci resi za tebe... tj. hlavne pro tebe podstatne bezbecnostni otazky ;-) nicmene zalezi samozrejmne na tobe, je to jen tip lineho programatora :D

Diskobolos

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #7 kdy: 10. 09. 2012, 15:26:01 »
Použij nějaký Framework (Zend, Nette, ...) nebo samotné ORM (NotORM, Doctrine, ...) pro zápis dat do DB. Framework ti pohlídá/ovaliduje obsah formuláře (většinou mají i antispam formulářovou komponentu) a ORM obálka zajistí korektní uložení do DB. Nemusiš pak tyto problémy vůbec řešit...

Jakub

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #8 kdy: 10. 09. 2012, 15:26:24 »
no já si po dvou letech předělal web tak sem si to chtěl i v hlavě oživit a proto se raději ptám jestli sem něco nezapomněl

PJ

Re:PHP - ochrana formuláře proti spamu a injekci mysql
« Odpověď #9 kdy: 10. 09. 2012, 15:49:23 »
... Pokud ano stránka se zobrazí.
A ako funguje zobrazenie tej stranky? A co presne sa uklada do DB? Tam je problem, ze keby sa ako 1 udaj do mena (alebo niekam) zadal "rozkaz" pre uzivatelov prehliadac, aby sa potvrdili vsetci neaktivni, tak sa to vykona s pravami cloveka, ktory navstevuje tu stranku na schvalenie.

DK

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #10 kdy: 10. 09. 2012, 16:12:17 »
Squirrel: kdyz uz, tak PDO

Jakub: ano, je to chybne, protoze to vicemene temer vubec nebrani sql injekci, mysql_real_escape_string dela pouze to, ze escapuje specialni znaky pouzivane v query, takze tim nespustia druhou query... porad ale muzes vyresetovat podminku, pokud nepouzijes to PDO, tak pouzij jeste sprintf

tj
Kód: [Vybrat]
$prepared = sprintf("SELECT * FROM tabulka WHERE stlpec='%s'", mysql_real_escape_string($_POST['hodnota']));
$q = mysql_query($prepared);

ale ani toto neni 100%, zato u pdo je to bezpecne

Jakub

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #11 kdy: 10. 09. 2012, 16:24:03 »
Uživatel zadává položky které nejsou pro administraci webu směrodatné.
Všechny údaje které se vkládají jsou předem prohnány nejprve přes mysql_realy_string a
pak jsou teprve vloženy do query... Tak nevím jestli sem teď správně odpověděl ....

pokud chapu co napsal DK  tak pokud mám přikaz:

$promena1=mysql_real_escape_string($POST_['data1']);
$promena2=sprintf(formatovaci prikaz,($promena1));
$prikaz=mysq_query("INSERT INTO user (jmeno) VALUES ('$promena2')");
 

Jakub

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #12 kdy: 10. 09. 2012, 16:24:54 »
tak bych měl navýšit možnost zabránění injekci MYSQL

DK

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #13 kdy: 10. 09. 2012, 16:33:20 »
Jakub: ne, vubec to nechapes

Kód: [Vybrat]
$data=mysql_real_escape_string();
$prikaz=sprintf("mysql query s pouziti %s, %d apod, viz manual",$data);
$query=mysql_query($prikaz);


timhle navysis moznost zabraneni mysql injection, ale PORAD to nebude stoprocentni, zatimco pri pouziti pdo by to bylo takhle
Kód: [Vybrat]
$pdo=new PDO(...);
$prepared = $pdo->prepare("SELECT * FROM tabulka WHERE id = :id);
$prepared->bindParam(":id",$id,PDO::PARAM_INT); //PDO::PARAM_STR pro vsechno ostatni
$prepared->execute();
$row=$prepared->fetch(PDO::FETCH_ASSOC); //->fetchAll(...) pro vice radku

Jakub

Re:PHP: ochrana proti spamu a injekci MySQL
« Odpověď #14 kdy: 10. 09. 2012, 16:57:49 »
A už je mi to jasné, takže místo proměnných sprintf odfiltruje přímo z příkazu nevhodné znaky :o)

O PDO slysším bohužel poprvé :O/
Takže to musí ještě počkat, pač web už musí dnes běžet.