Šta je novo?

SQL Injection

Ljanmi

Slavan
Učlanjen(a)
01.02.2006
Poruke
2,075
Poena
380
Drugari vidim da krcate PHP a ja sam totalan pocetnik :( Zelim da dodam pretplate na svojoj stranici, dakle samo mi treba unos imeila tako da sam kreirao SQL bazu " pretplate", table "klijenti" sa id-em(integer, primary, incremetal, lenght 11) i emal(varchar, lenght 50) - tip baze mislim da je inoDB ako je to bitno uopste. Evo ga kod koji uredno upisuje u table medjutim voleo bih opciju da ne mogu 2x da unesem istu adresu kao i da adresa mora da sadrzi "@" i ".com" . Ako moze mala pomoc, kapiram da je ovo smesno za PHP mastere a meni mnogo znaci kao pocetniku :) Hvala unapred.


PHP:
<?php

$con=mysqli_connect('localhost','root','');
if(!$con) {
	echo 'Nema postoji veza sa serverom';
}
if(!mysqli_select_db($con,'pretplate'))
{
	echo 'Nema veze sa bazom podataka';
}
$email = $_POST['email'];
$sql = "INSERT INTO klijenti (email) VALUES ('$email')";
if(!mysqli_query($con,$sql))
{
	echo 'podaci nisu uneti';
}
else 
{
	echo 'BIĆETE OBAVEŠTENI O NOVIM MODELIMA';
}

header("refresh:2; url=index.html");
?>
 
Za email ti treba regular expression, potrazi na stackoverflow, ili najjednostavnije (ali nije preporucljivo), da stavis <input type="email" required> i onda nece da ti dozvoli da uneses nesto sto nije email adresa. Za ovo prvo, u mysql tabeli stavi unique kod email-a.
 
Za email ti treba regular expression, potrazi na stackoverflow, ili najjednostavnije (ali nije preporucljivo), da stavis <input type="email" required> i onda nece da ti dozvoli da uneses nesto sto nije email adresa. Za ovo prvo, u mysql tabeli stavi unique kod email-a.
Ql, ThX na brzoj podršci!

A što nije preporučljivo <input type="email" required> , deluje baš onako "elegantno" što se kaže :)

Sent from my Nexus 5X using Tapatalk
 
Zato sto je to client-side provera i moze da se zaobidje. Postoji nesto sto se zove SQL Injection... Obavezno se radi i server-side provera pre upisa u bazu.
 
Tako je, ako ne vodis racuna moze SQL Injectionom da ti izvuce celu bazu.
 
Pa dobro, sta moze da preko email input-a pristupi kompletnoj SQL bazi na taj nacin i na primer iscita sve mailove koje su mi ljudi ostavljali?

Nisam neki veliki strucnjak iz te oblasti ali SQL Injection-om moze da ti napravi mnogo vecu stetu nego sto je samo da iscita podatke iz baze. Moze recimo i da ti obrise celu bazu, tabelu, promeni vrednosti... Ako imas dodatna pitanja pretrazi malo forum ili otvoru novu temu da nam se shone83 ne ljuti.
 
Pa da, umesto i sam da nauči nešto plače što smo malo skrenuli sa teme. Inače odradio sam sve u fulu, baš sam zadovoljan. Otvoriću kasnije drugu temu vezano za SQL injection pošto nisam imao pojma za to a voleo bih da čujem kako mogu da se zaštitim.

Sent from my Nexus 5X using Tapatalk
 
Nešto neće da radi link... Na yt potražite Computerphile Running an SQL Injection Attack

Sent from my Nexus 6P using Tapatalk
 
Poslednja izmena:
Drugari vidim da krcate PHP a ja sam totalan pocetnik :( Zelim da dodam pretplate na svojoj stranici, dakle samo mi treba unos imeila tako da sam kreirao SQL bazu " pretplate", table "klijenti" sa id-em(integer, primary, incremetal, lenght 11) i emal(varchar, lenght 50) - tip baze mislim da je inoDB ako je to bitno uopste. Evo ga kod koji uredno upisuje u table medjutim voleo bih opciju da ne mogu 2x da unesem istu adresu kao i da adresa mora da sadrzi "@" i ".com" . Ako moze mala pomoc, kapiram da je ovo smesno za PHP mastere a meni mnogo znaci kao pocetniku :) Hvala unapred.


PHP:
<?php

$con=mysqli_connect('localhost','root','');
if(!$con) {
	echo 'Nema postoji veza sa serverom';
}
if(!mysqli_select_db($con,'pretplate'))
{
	echo 'Nema veze sa bazom podataka';
}
$email = $_POST['email'];
$sql = "INSERT INTO klijenti (email) VALUES ('$email')";
if(!mysqli_query($con,$sql))
{
	echo 'podaci nisu uneti';
}
else 
{
	echo 'BIĆETE OBAVEŠTENI O NOVIM MODELIMA';
}

header("refresh:2; url=index.html");
?>

Izuzecu ovaj deo sa MySQL-om posto je trenutno irelevantan. Bitan momenat je ovaj:
Kod:
$email = $_POST['email'];

Prvo i najvaznije pravilo prihvatanja bilo kod tipa HTTP zahteva u bilo kom programskom jeziku je - nikad ne veruj posiljaocu, pa makar to bio i ti sam. alphablue597 je pomenuo regularni izraz, ali u tvom slucaju to nije potrebno posto PHP poseduje odlicnu funkciju filter_var (http://php.net/manual/en/function.filter-var.php) koja moze da se iskoristi za tu namenu:
Kod:
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

Na ovaj nacin, string za koji ne znamo sta je biva provucen kroz filter, a koji na osnovu datog parametra koristi vec unapred odredjeni regularni izraz i vrsi promene po stringu. Da li to znaci da smo i dalje bezbedni? Ne. Logican korak bi bio:
Kod:
 if(!filter_var($email, FILTER_VALIDATE_EMAIL)) die("Uneti string nije ispravna e-mail adresa");

Ako se malo obrati paznja, jasno je da postoji razlika izmedju FILTER_SANITIZE_EMAIL i FILTER_VALIDATE_EMAIL - prvi vrsi mutaciju, a drugi samo validaciju.

Na kraju, ako bi se dotakli i tvog SQL upita, ni on nije savrseno bezbedan - nisi preduzeo sve korake neophodne da se obezbedis (jer i filteri i regularni izrazi mogu da propuste nesto sto ne treba - ne veruj ni njima). Ispravan upit bi izgledao ovako:
Kod:
mysqli_query($con, sprintf("INSERT INTO klijenti (email) VALUES (%s)", $email));

.. ili koriscenjem adekvatnih metoda koje MySQLi sam po sebi (bind param i sl.).
 
Kao prvo zaista sam zahvalan na ovakvom vrhunskom odgovoru. Bas si objasnio super za ljude koji nemaju pojma. U aplikaciji sa Androida iz koje sam ucio nisam imao "filter_var, FILTER_SANITIZE, FILTER_VALIDATE", ali pazi ovo "sprintf" - nemam pojma sta znaci :) kao ni (%s) :) Ovo "%" je modulus valjda, to sam lepo izucio ali vezano za integer tj brojeve tipa

PHP:
<?php
$x=14;
$y=3;
echo $x % $y; //printovace 2
?>

Verovatno se neko upisava od smeha ali dobro :)

Html code koji sam upotrebio na stranici izgleda ovako:

HTML:
<form id="forma" action="insert.php" method="POST" autocomplete="on">
<input  placeholder="Unesite vašu email adresu ovde" required="" type="email" name="email" pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,63}$"><br>
<input id="dugme" type="submit" value="Želim da budem obavešten o NOVIM modelima" name="Submit">
</form>

Stavio sam pettern sad dal je to greska? Citao sam na stackoverflow o email inputu na predlog kolege alphablue597 i nasao ovo kao najbolje resenje(jer je najsveziji i apdejtovan code u odnosu na selektovani zelenom bojom :) ) - This is modified version of above solution which accept capital letter as well
HTML:
<input name="email" type="email" pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,63}$" class="form-control" placeholder="Email*" id="email" required="">
Sada cu da pokusam da "sklopim kockice" sa FILTER_SANITIZE i FILTER_VALIDATE, pa se opet javljam sta sam uradio :) Pustio bih link od stranice ovde sada ali nije online, code izvrsavam sa virtualnog hosta - XAMPP Control Panel V3.2.2(sa WAMP-om iz nekog razloga nisam imao srece da upisujem podatke u bazu podataka iako je isti code u pitanju? - jos zamislite drustracije koje sam imao kada sam prvi put u zivotu video i kreirao SQL bazu gledajuci jutjub i pokusavao da je povezem i upisem bilo sta u nju na bilo koji nacin :exploder: - a sa XAMPP-om sve iz prve se povezalo i proradilo).
PS
HTML i CSS za moje potrebe poznajem savrseno, java script editujem po potrebi, retko kada pisem nesto potpuno sam jer nikako da sednem i da pocnem to da ucim dok sam PHP "kao" poceo da ucim i nije da ne razumem - opet za moje potrebe. Ovo ne radim zato sto planiram bilo kada da zaradim jedan jedini dinar od PHP-a i javascript-a vec zato sto sam igrom slucaja digao neka 2 sajta za svoje potrebe i stalno ih nesto unapredjujem, dodajem, jednostavno nema kraja :) Traje sve ovo jedno 2,5-3 godine, dosta, dosta vremena ulozeno u hobi, vremenom sam poceo da bas uzivam u svemu tome, rad u Sublime-u sa Emmetom poredivo sa igranjem igara :)

Update:

Video sam da "%" nije modulus vec deo sprintf() Function-a :D

%% - Returns a percent sign
%b - Binary number
%c - The character according to the ASCII value
%d - Signed decimal number (negative, zero or positive)
%e - Scientific notation using a lowercase (e.g. 1.2e+2)
%E - Scientific notation using a uppercase (e.g. 1.2E+2)
%u - Unsigned decimal number (equal to or greather than zero)
%f - Floating-point number (local settings aware)
%F - Floating-point number (not local settings aware)
%g - shorter of %e and %f
%G - shorter of %E and %f
%o - Octal number
%s - String
%x - Hexadecimal number (lowercase letters)
%X - Hexadecimal number (uppercase letters)
 
Poslednja izmena:
Sanitajz i validejt filteri su mi skroz jasni, sprintf 'nako - kapiram od prilike sta radi ali ne i kako se korisno primenjuje. To bi trebalo ovako da izgleda(jedino ovako mi i radi, nisam znao bolje)?
Ovaj deo mi nije jasan i ne mislim da sam napisao kako treba, sve ostalo sto sam logicno probao nije urodilo plodom, zato sam ga ostavio onako.

PHP:
mysqli_query($con, sprintf("INSERT INTO klijenti (email) VALUES (%s)", $email));



PHP:
<?php

$con=mysqli_connect('localhost','root','');
if(!$con) {
	echo 'Nema postoji veza sa serverom';
}
if(!mysqli_select_db($con,'pretplate'))
{
	echo 'Nema veze sa bazom podataka';
}
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) die("Uneti string nije ispravna e-mail adresa");
$sql = "INSERT INTO klijenti (email) VALUES ('$email')";
mysqli_query($con, sprintf("INSERT INTO klijenti (email) VALUES (%s)", $email));
if(!mysqli_query($con,$sql))
{
	echo 'VAŠA EMAIL ADRESA JE VEĆ ADRESIRANA';
}
else 
{
	echo 'BIĆETE OBAVEŠTENI O NOVIM MODELIMA';
}
header("refresh:2; url=index.html");
?>


HTML:
<form id="forma" action="insert.php" method="POST" autocomplete="on">
<input  placeholder="Unesite vašu email adresu ovde" required="" type="email" name="email" pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,63}$"><br>
<input id="dugme" type="submit" value="Želim da budem obavešten o NOVIM modelima" name="Submit">
</form>
 
Poslednja izmena:
@ ljanmi

%d, %c... - specifikatori tipa (mogu se koristiti i u drugim funkcijama)

Sent from my m2 using Tapatalk
 
Neko moze da sa inspect element izmeni formu, obriše pattern i submituje šta poželi. Niste dobro shvatili kutiju... Ne veruj mi sam sebi. Apsolutno mora da se proveri pre izvršavanja queryja, bez obzira da li je to neki bezazleni query ili neka izmena u bazi.

% u sprintf je mesto gde će se ubaciti vrednost. Npr...
Sprintf("%s ima %d računara i %d telefona u vrednosti od %f eur", $ime, $numcomp, $nummob, $total);
Prvi %s će umetnuti $ime, sledeći %d će biti zamenjen brojem u $numcomp, pa sledeći %d je $nummob i na kraju %f je broj sa zarezom.
sprintf vuče korene iz jezika C.



Sent from my Nexus 6P using Tapatalk
 
Poslednja izmena:
Ok, ucio sam malo printf i sprintf od cega mi je ovo prvo jasnije :) Koliko sam razumeo printf prikazuje a sprintf vraca string(sprintf ne kapiram bas najbolje ali nema veze). Npr koristeci printf mogu da isprintam ovako nesto:
PHP:
<?php
$L = 'Ljanmi';
$V='vežba';
$P='PHP';
printf("%'@9s", $L);
printf("%'@9s", $V);
printf("%'@6s", $P);
printf("%'@3s",'')
?>
cvc.jpg

Ako sam dobro razumeo uneti email mora biti niz u mom slucaju inace unos nece biti dozvoljen od strane servera jel? Za svoje potrebe uspeo sam da se snadjem i sredim deo koristeci sprintf funkciju:

PHP:
<?php

$con=mysqli_connect('localhost','root','');
if(!$con) {
	echo 'Nema postoji veza sa serverom';
}
if(!mysqli_select_db($con,'pretplate'))
{
	echo 'Nema veze sa bazom podataka';
}
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) die("Uneti string nije ispravna e-mail adresa");
$sql = sprintf("INSERT INTO klijenti (email) VALUES ('%s')", $email);
if(!mysqli_query($con,$sql))
{
	echo 'VAŠA EMAIL ADRESA JE VEĆ ADRESIRANA';
}
else 
{
	echo 'BIĆETE OBAVEŠTENI O NOVIM MODELIMA';
}
header("refresh:2; url=index.html");
?>

HTML:
<form id="forma" action="insert.php" method="POST" autocomplete="on">
<input  placeholder="Unesite vašu email adresu ovde" required="" type="email" name="email" pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{1,63}$"><br>
<input id="dugme" type="submit" value="Želim da budem obavešten o NOVIM modelima" name="Submit">
</form>

Ovo radi kako treba da radi, sad da li sam sve postavio kako treba da budem zasticen od SQL injection-a?

Ovo nema veze sa temom:
Isao sam korak dalje i malo se igrao, umesto ('%s') - stringa sam sam postavio ('%b')-binary , dakle u bazu podataka bi teoriski bilo moguce ubaciti samo cele brojeve jel? I to je ok, ne dozvoljava mi unos email adresa(jer nisu brojevi) ali druga stvar mi je cudna. Uvek i uvek mi adresira prvi unos nulom(0), posle toga prijavljuje gresku i ne reaguje ali prvi unos ulazi nulom regularno u bazu podataka. Mislim nije bitno uopste ali da podelim svoje neznanje :)

cvc.jpg


Hvala svima koji ucestvuju u temi :wave:
 
Moras da obecas da neces da hackujes benchmark forum kad naucis sve o SQL injection ;)
 
Nazad
Vrh Dno