Ob_start() használata
Sziasztok!
Azt szeretném megtudni, hogyan kell helyesen használni az ob_start(); ob_end_flush(); függvényt? Az átirányítást szeretném, hogy működjön!
■ Azt szeretném megtudni, hogyan kell helyesen használni az ob_start(); ob_end_flush(); függvényt? Az átirányítást szeretném, hogy működjön!
<?php
$kuld=$_POST['kuld'];
$name=$_POST['name'];
$pass=md5($_POST['pass']);
if(isset($kuld) and isset($pass) and isset($name)){
$result=mysql_query("SELECT * FROM user WHERE name='$name' and pass='$pass'") or die (mysql_error());
if(mysql_num_rows($result)==1){
while($row=mysql_fetch_array($result)){
$acti=$row['acti'];
$name=$row['name'];
$admin=$row['admin'];
}
if($acti==2){
$_SESSION['admin']=$admin;
$_SESSION['name']=$name;
header("Location: $_SERVER[PHP_SELF]");
}else{ ?><script language="javascript">alert("Nincs aktiválva a regisztrációd");</script><?php }
}else{ ?><script language="javascript">alert("Hibás felhasználónév és/vagy jelszó");</script><?php }
}else{
?>
<form method="post">
Felhasználónév:<br /><input type="text" name="name" /><br />Jelszó:<br /><input type="password" name="pass" /><br /><input type="submit" value="Belépek" name="kuld" />
</form>
<?php
}
?>
Miért?
ob_start
-ra. Egyszerűenexit
-elj az átirányítás után.Hiba
nem mondtad
ob_start()
, majd a végén, amikor már tényleg ki akarsz írni valamit, akkorob_end_flush()
.Ezen kívül érdemes lenne átírni az adatbázis lekérdezésedet, mert most nagyon veszélyes SQL Injection tekintetében. Akkor is illik a felhasználónak kiírni a hibát, ha nincs nála bekapcsolva a JavaScript. Valamint jobb lenne, ha nem használnál ilyet, hogy
"Location: $_SERVER[PHP_SELF]"
, helyette legalább"Location: " . $_SERVER['PHP_SELF']
. Ha ezeket kijavítod, talán Crystal is jobban tud majd aludni.Hát lehet...
Kicsit belejavítva, átrendezve
Egy alap függvényt használtam az SQL injection kivédésére, ami a mysql_real_escape_string(). Ez részben azt csinálja, hogy az összes olyan "veszélyes" karaktert kiszűri, amivel kilehet lépni a MySQL lekérésből.
Például:
Ha az $USER értéke ez lenne:
A drop table meg ügye az "xy" adatbázist kompletten letörölné :).
Na íme a változtatott kód:
A biztonságot persze még számtalan módszerrel lehet csiszolni:
- túl sok hibás belépés után kitiltás
- captcha megkövetelése a belépéshez (x hibás belépés után)
- stb..stb..stb..
PS:
Valamiért a kód színező az alábbi eredményt adta, hol nem is ezt írtam:
Tehát a helyes:
Remélem tudtam segíteni. :-)
Üdv,
Bence
ez sem az igazi.
Inkabb PDO es prepared statements: http://php.net/manual/en/pdo.prepared-statements.php
Nem tökéletes kód amit írtam,
PS: Szerintem egy jól megírt MySQL wrapper jobb választás volna.
Például:
http://www.ricocheting.com/code/php/mysql-database-class-wrapper
Ne terjesszünk hülyeséget!
A nevezett függvény helyes használata az, ha mysql_set_charset függvénnyel megmondjuk a PHP-s MySQL libnek a karakterkódolást, majd macskakörmök között beadjuk a mysql_real_escape_string-elt információt. Értem én, hogy rá vagyunk pattanvan a PDO-ra, de ne higyjük már, hogy az a szent grál és minden más szar.
re
En egyaltalan nem vagyok rapattanva a PDO-ra, szent gralnak sem tartom, de szerintem a nativ mysql library-nal jobb.
mysqli_prepare(). problem
;]
Programozni
A másik viszont az, hogy rengeteg olyan "fejlesztővel" találkoztam már, aki a fentihez hasonló cikkekből kiindulva váltig állította, hogy a natív MySQL library szar és közben lövése nem volt a dolgok hátteréről, ezért hevesen ellenzem a fentihez hasonló cikkek terjesztését. Tipikus szenzációhajhász, szándékos vagy tudatlanságból adódó ferdítéseket tartalmazó írás. Inkább elmondhatta volna a t. szerző, hogy mi a dolog háttere és hogy kell ellene védekezni.
A mysql library (feltéve,
később valamivel egyszerűbb
Egyszer
Amennyire tudom (láttam/meg
Én csak rendszergazdaként
Ne abban gondolkodj, hogy x megrendelőnek készítesz y rendszert, hanem mondjuk a Drupal készítőinek a fejével! Ők nem készülhetnek arra, hogy kizárólag MySQL-t tehetnek a rendszerük mögé. (bocs, Drupal csak egy hirtelen jött példa volt, nem tudom, képes-e mást is használni)
Értem, tehát a feladata
test
Ha az az integer érték type
De lehet én értettem valamit félre, amire gondolok:
- mysql_real_escape_string() - csak mysql esetén, amúgy addslashes() még esetleg (az is jobb, mint a semmi)
- PDO::quote()
vagy PDO prepared statement esetén - tehát a PDO::prepare() hívással visszakapott objektumon hívott - PDOStatement::bind***() metódusok használata, ha az előző kettő nem felel meg a céloknak vagy a meglévő eszközökkel nem teljesen férnek össze.
Persze ha adatbázis absztrakciós réteget használunk a PDO (vagy bármi) felett, akkor annak a dokumentációja mérvadó - a kulcsszavak ebben az esetben: "SQL injection", "SQL security", "escaping SQL queries" és hasonlók :)
A bind-olt megoldást miért
csak hogy írjak valami konstruktívat is
ha most kezded a PHP-t akkor erősen javallanám ennek a könyvnek a beszerzését: http://www.sitepoint.com/books/phppro1/toc.php
Ezen kívül a legtöbb szakirodalom elavult, a "netes tutorialok" 95%-ának pedig a béka segge alatt van a minősége. Ha ezekből tanulsz, akkor csak nagyon sokára fogod rendesen megtanulni a szakmát.
A fenti könyvöm kívül a php.net legyen az elsődleges információforrásod, továbbá érdemes lenne elkezdened hasznléni egy keretrendszert minél hamarabb (ha már pár hónapja tanulsz akkor pont ideje). Egyrészt azért, mert elég sokat segítenek abban, hogy ne olyan "éppen működő de amúgy katasztrofális" kódot írj, másrészt mert rengeteget fejlődhetsz, ha belenézel a forráskódjukba, harmadrészt mert - ha kellő tapasztalatod van egy adott rendszer használatában - akkor jelentősen gyorsítják a fejlesztés sebességét. Később persze dönthetsz úgy, hogy nem kell neked semmilyen keretrendszer, vannak seniorok között is ilyen no-framework fejlesztők, de egyelőre - elsősorban tanulási célból - nagyon javallott valami framework használata.
uh. ma is rosszat fogok
BOM
Milyen SQL-Injection?!
Ott van az a feltétel, hogy:
if(mysql_num_rows($result)==1)
, ami - szerintem - egyértelműen jelzi, hogy csak 1 db eredmény esetén ok!Megjegyzem, én ezután még ráellenőriznék, hogy a
$result[name]==$name and $result[pass]==$pass
és akkor már majdnem tutira mentem, mindenféle real_escape-ek nélkül, és akkor nem is kell vitatkozni annak használhatóságáról...fail
2. Hecc kedvéért jelszóként kapott injection végére még odabiggyeszt egy LIMIT 1-t és akkor a sorszámlálód már semmit sem ér.
Ha meg az adatbázisban plain textben tárolod a jelszavakat... na erre inkább nem mondanék semmit.
re: fail
2. Köszönöm a kiigazítást ezt most tényleg benéztem, mentem az oldalt figyelmeztetőnek!
Nem én, egyébként van rajta - ha jól láttam - md5, én azt a változót használtam... Persze lehetne több, mint md5.
Későbbi szerk.:
,tehát 2.-ben "nem annyira" köszönöm a kiigazítást, kiragadtad egy mondatomat, nem tekintve, hogy mit írtam utána. Sztem így is lehet, nem csak realslash-el. Ha nem ok, akkor bocs a tévedésért.
Sokan írták a veszélyt, én
mapdesign18 a veszély szemléltetésével kezdi a hozzászólását. Olvasd el.