PHP-Script.hu
Kiemelt hirdetés:
2018. április 23. 13:33 hétfő, ma Béla névnap van


grafika


Videóbázis


Kategória: PHP
Biztonságos űrlapok készítése
2011.06.13. 16:50

Sokan estünk már abba a problémába bele, hogy csináltunk egy nagyon jó kis űrlapot, és csak később jöttünk rá, hogy hoppá ez nem lett jó, bárki tudja kalibrálni az oldalt vele. Na most ezt próbáljuk nektek megmutatni, hogy hogyan is lehet levédeni az oldalt, a kíváncsiskodók elől.


Sokszor előfordulhat az, hogy nem vesszük figyelembe a felhasználókat, mivel azt gondoljuk, hogy tudják hogyan kell az űrlapot használni, pont úgy ahogy mi megterveztük. Na ezt most rögtön el is lehet felejteni, mert mivel nem mindenki használja úgy az oldalt, ahogy mi gondoljuk. Vannak, akik ennek kárárra akarnak törni, hiszen nekik céljuk az, hogy nekünk ne legyen jó. Ilyenek például a robotok, de ők nem kárt akarnak nekünk okozni, de még ott vannak az úgy nevezet "hackerek" (akik magukat annak mondják, hiszen egy egyszerű SQL INJECT-re bárki képes). Nevetés

 

Most nézzük meg, milyen is egy egyszerű űrlap kitöltés, és annak adatainak továbbítása az adatbázisba:

1
2
3
4
5
<form method="post" action="send.php">
Nick: <input type="text" name="nick" size="20"><br>
Szöveg: <textarea name="szoveg" cols="20" rows="5"></textarea><br>
<input type="submit" value="Küldés">
</form>

A fentebi kódban minden tisztán látható, ez egy HTML űrlap, ami egy "Nick" nevet és egy "Szöveg" mezőbe kéri az adatokat. Jól látható, hogy az inputok neve a "nick" és a "szoveg". Ezeket fogjuk felhasználni a send.php-ba, ami értékeli az adatokat.

Most vigyük át az adatokat a php-nak.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$nick = $_GET["nick"];
$szoveg = $_GET["szoveg"];
 
//Kapcsolódás az adatbázisra
$host = "localhost";
$user = "user";
$pass = "jelszó";
$base = "adatbázis";
 
$dbc = mysql_connect($host, $user, $pass) or die ("Hiba a csatlakoznál!");
mysql_select_db($base, $dbc) or die ("Nem létezik az adatbázis!");
 
$query = "INSERT INTO uzenet (nick, szoveg, aktiv, datum) VALUES ('$nick', '$szoveg', '0', NOW());
mysql_query ( $query, $dbc);
 
mysql_close($dbc);
 
echo "Adatok elküldve!";
?>

Na akkor most nézzük meg ezt közelebbről, ahogy látható változókban tároljuk a "nick" és a "szoveg" mező adatait. Ezért volt fontos, hogy megegyezenek a HTML-ben található input name-kkal. Ezek után kapcsolódtunk az adatbázishoz, aminek először az elérési adatait tároltuk változókban, majd felcsatlakoztunk. Ez után a feltöltés maga zajlik le, ahol jól látható, hogy a $nick, és a $szoveg változót vitük fel, a "0"-val azt jelöltük, hogy még nem lesz látható, mivel nem akarjuk, hogy olvassa mindenki. a NOW() függvény egy nagyon okos kis függvény, mivel ezzel a pontos időt adjuk meg neki, amikor lefut a script. Majd végül lezártuk az adatbázist, mivel így egy slotot szabadítunk fel, hogy máshol újabb mysql csatlakozás mehesen végbe.

Na itt jön a probléma, bárki egyszerűen tud üres mezőket küldeni, na ezt most védjük le. Ehhez most megint a send.php-hoz kell nyúlnunk, mivel ott kell levédenünk az adatokat.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$nick = $_GET["nick"];
$szoveg = $_GET["szoveg"];
 
//Kapcsolódás az adatbázisra
$host = "localhost";
$user = "user";
$pass = "jelszó";
$base = "adatbázis";
 
if (!empty($nick) && !empty($szoveg)) {
$dbc = mysql_connect($host, $user, $pass) or die ("Hiba a csatlakoznál!");
mysql_select_db($base, $dbc) or die ("Nem létezik az adatbázis!");
 
$query = "INSERT INTO uzenet (nick, szoveg, aktiv, datum) VALUES ('$nick', '$szoveg', '0', NOW());
mysql_query ( $query, $dbc);
 
mysql_close($dbc);
}
echo "Adatok elküldve!";
?>

Most már levédtük az oldalt, hogy üres mezők ne lehesenek az adatbázisban, ez fontos, mivel mi értelme van üres szöveget elküldeni üzenetben?! Nézzük is meg újra a kódot. Ahogy látjuk empty() függvényt használtunk, ez azt nézzi, hogy üres-e a változó, de mivel mi tettünk oda egy "!" jellet ezzel azt nézzük, hogy nem üres a változó, mivel nekünk ez kell, és ez alatt amit látunk az if alatt, akkor teljesül, ha a "$nick" és a "$szoveg" változó nem üres. Most már fél siker van.

Hoppá, bajok vannak. Valaki feltörte az oldalt, valahogy aktíválta az üzenetet, így mindenki láthatja. Na itt jön elő az, hogy mégse vagyunk valami biztonságos oldalon. Ezért minket fognak elővenni, hogy mit is csináltunk az oldallal. Na de nézzük meg jobban, hogy mi is törtét az oldallal. Egyik felhasználó rá lelt arra, hogy egyszerűen tud SQL INJECT-telni. Hát ezt először is hadd mutasam be, hogy miről is van szó.

Egy SQL INJECT, a mai világ egyik leggonoszabb dolga, amit egy felhasználó tud végezni egy oldallal. Az SQL INJECT egy beinjekciózás az adatbázisba, mivel nem is kell sokat tennie, hogy olyan dolgokat alakítson át, amit mi nem is szeretnénk, meg nem is engedünk neki, hogy hozzá férjen. Az előző példát vegyük.

Szöveg mezőben az alábbi sorokat írja a kedves felhasználónk: "'HEHEHE FELTÖRTEM AZ OLDALT!', '1')--"

Na most ha ezt megkapja maga a send.php programunk, és a query résznél ez fog zajlani.

1
$query = "INSERT INTO uzenet (nick, szoveg, aktiv, datum) VALUES ('Én', 'HEHEHE FELTÖRTEM AZ OLDALT', '1')--;

Hát igen, jól látható, hogy a dátum nem is kapja meg, és a "0" helyet meg egy "1"-est küld el így a scriptünk. Ez annak köszönhető, hogy nem védtük le az oldalt, és a felhasználó szabadon garázdálkodhat az oldalon.

Na, de most jön a PHP és a MYSQL közös visszacsapása, amit most nektek is megmutatok, hogy hogyan is védhetjük ki az ilyen eseményeket.

Az egyik ilyen a tim() függvény, ami a szavak előtti és utáni szóközöket eltünteti, így szóközök nélkül, kisebb az esély a támadásra.

A másik ilyen függvény pedig a mysql_real_escape_string(), ami a veszélyes karaktereket a " és a ' meg a többi speciális karaktert levédi, így semmi kárt nem tudnak okozni az oldalban.

Na most nézzük meg, hogyan is lehetne ezt átvinni a forrásunkba. Érdemes mind a kettőt használni, mivel így nagyobb a biztonság.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$nick = mysql_real_escape_string(trim($_GET["nick"]));
$szoveg = mysql_real_escape_string(trim($_GET["szoveg"]));
 
//Kapcsolódás az adatbázisra
$host = "localhost";
$user = "user";
$pass = "jelszó";
$base = "adatbázis";
 
if (!empty($nick) && !empty($szoveg)) {
$dbc = mysql_connect($host, $user, $pass) or die ("Hiba a csatlakoznál!");
mysql_select_db($base, $dbc) or die ("Nem létezik az adatbázis!");
 
$query = "INSERT INTO uzenet (nick, szoveg, aktiv, datum) VALUES ('$nick', '$szoveg', '0', NOW());
mysql_query ( $query, $dbc);
 
mysql_close($dbc);
}
echo "Adatok elküldve!";
?>

Most már jól látható, hogy nincsenek gondok, mivel már nem tudnak minket támadni űrlapon keresztül.

Remélem sokat segítettem ezzel nektek, hogy továbbiakban egy SQL INJECT-et kitudjatok védeni. Ha bármi probléma akad, nyugodtan írjatok, szívesen segítünk.


 Szerző: useriNferNaL Hozzászólások(3) Hozzászólások Megosztás az iWiW-en Megosztás az Facebook-on Megosztás a Google Reader-ben Megosztás az Twitter-en 

Listázás:  Idő szerint:
Webprogramozás arr Tutorialok info Biztonságos űrlapok készítése
(#3) szaby 2013.05.29. 12:42

szaby
szaby
Kezdő

Ez nem egészen jó kód. Miért is?

Fentebb az űrlapnál $_POST-al küldöd a nick-et és szoveget.
Lentebb a send.php-nál meg már $_GET-el... Már eleve nem biztonságos $_GET-el dolgozni. Mindent ha lehetséges $_POST-olni kell.

Szaby

(#2) RimElek válasza erre: (#1) Menrich Brother 2011.06.17. 20:39

RimElek
RimElek
VIP

Hogy milyen veszélyes karaktereket értett infernal alatta, azt megtalálod a php dokumentációban a mysql_real_escape_string függvénynél. Fel van sorolva: \x00, \n, \r, \, ', " and \x1a

A trim pedig természetesen a szélekről veszi csak le a szövegben a szóközöket. Nem sok haszna lenne ellenkező esetben :)

(#1) Menrich Brother 2011.06.17. 14:04

Menrich Brother
Menrich Brother
Kezdő

Veszélyes karakterek alatt mit értesz, mert szerintem nem csak a ' és a " van. Anno mikor én próbáltam hasonló űrlapot készíteni én a preg_replace függvénnyel játszottam. A másik kérdés, hogy a trim csak az átadott változóban levő szóközöket is eltünteti vagy csak a szó elejéről és végéről. Gondolok arra ha mondjuk ez lenne: " Hello Világ ". Akkor a kimenet simán a Hello Világra fog vonatkozni, vagy ez lesz: HelloVilág?

Válaszodat előre is köszönöm.kep

Listázás:  Idő szerint:


© 2006-2018 PHP-Script.hu, Minden jog fenntartva!
Design: Rácz Gergely, Oldalmotor: Rácz Gergely
Impresszum - Oldaltörténet - Oldalszabályzat