Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQL] - $id i mysql_real_escape_string
Forum PHP.pl > Forum > Przedszkole
Mega_88
Cześć !

Temat logowania oraz sql injection przerobiłem z Wami w poprzednim temacie wszystko pięknie.

Natomiast czytając temat w dziale PHP "SQL Injection/Insertion" nie mogę lub w gąszczu kłótni nie znalazłem jasnej odpowiedzi.

Mam taki kod, mniej więcej struktura strony opiera się na tym ( ucięte to co zbędę zostawiłem tylko to co jest chyba potrzebne ), dodałem do tego mysql_real żeby filtrowało mi id

  1. <?php
  2. $id = mysql_real_escape_string($_GET['id']);
  3. if(isset($_GET['id'])) $id = $_GET['id']; else $id = 1;
  4. $query = mysql_query("SELECT * FROM strony WHERE id=$id");
  5. while($wynik=mysql_fetch_array($query)) {
  6. echo $wynik['tytul'];
  7. }
  8. ?>


I moje pytanie po wpisaniu: www.domena.pl/index.php?id=1' wywala mi błąd:

  1. Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /home/.../index.php on line 154


Więc czy dobrze mi się wydaje strona nadal jest podana na sql injection ? Bo błąd chyba nie powinien się pojawiać, a czy mam mysql_real czy nie to błąd ciągle ten sam. Filtrowanie zrobiłem podobne do tego z tematu logowania i tam działa poprawnie, magic_quotes_gpc mam na off

Uprzedzę już pewne odpowiedzi: wiem, że PDO będzie lepsze jednak chciałbym przeronić mysql'a
Ruch Radzionków
zamień to:

  1. $query = mysql_query("SELECT * FROM strony WHERE id=$id");


na
  1. $query = mysql_query("SELECT * FROM strony WHERE id='$id'");
Mega_88
Tak na szybko zamieniłem, ale komunikat błedu mam nadal ten sam...

  1. Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /home/.../index.php on line 154
Ruch Radzionków
  1. <?php
  2. if(isset($_GET['id'])) $id = $_GET['id']; else $id = 1;

spróbój zmienic na takie coś
  1. if(isset($_GET['id']))
  2. {
  3. $id = $_GET['id'];
  4. }
  5. else
  6. {
  7. $id = "1";
  8. }
Mega_88
Dobra z pomocą i chwilę pokombinowałem obecnie wygląda to tak:

  1. <?php
  2. if(isset($_GET['id'])) $id = $_GET['id']; else $id = 1;
  3. $id = mysql_real_escape_string($_GET['id']);
  4. $query = mysql_query("SELECT * FROM strony WHERE id='$id'");
  5. while($wynik=mysql_fetch_array($query)) {
  6. echo $wynik['tytul'];
  7. }
  8. ?>


Po wpisaniu w URL - www.domena.pl/index.php?id=1' nie wyświetla się żaden błąd i strona działa prawidło, czy to znaczy że obecnie zwykły "Kowalski" nie będzie mógł w łatwy sposób kombinować ?

Oraz mam jeszcze jedno pytanie. Rozumiem, że teraz konieczne będzie zmienie w funkcjach z $id na '$id' w poleceniach SELECT jak na przykład ta poniżej ?

  1. function langLink($id,$lang) {
  2. $query="select * from strony where id='$id'";
  3. $wyk=mysql_query($query);
  4. $wynik=mysql_fetch_array($wyk);
  5. switch($lang) {
  6. case "pl": {
  7. return $wynik['tytul']; break;
  8. }
  9. case "en": {
  10. return $wynik['tytulen']; break;
  11. }
  12. }
  13. }
Ruch Radzionków
tak bo musisz miec wybrane co tam sie ma znajdowac bo to może byc nawet napis i tak bedziesz to musiał dac w nawias
Mega_88
Cytat(Ruch Radzionków @ 28.03.2013, 01:11:18 ) *
tak bo musisz miec wybrane co tam sie ma znajdowac bo to może byc nawet napis i tak bedziesz to musiał dac w nawias


Czyli powinno być w ten sposób ?

  1. function langLink($id,$lang) {
  2. $query=("select * from strony where id='$id'");
  3. $wyk=mysql_query($query);
  4. $wynik=mysql_fetch_array($wyk);
  5. switch($lang) {
  6. case "pl": {
  7. return $wynik['tytul']; break;
  8. }
  9. case "en": {
  10. return $wynik['tytulen']; break;
  11. }
  12. }
  13. }



A jak z odpowiedzią na moje pytanie:

"Po wpisaniu w URL - www.domena.pl/index.php?id=1' nie wyświetla się żaden błąd i strona działa prawidło, czy to znaczy że obecnie zwykły "Kowalski" nie będzie mógł w łatwy sposób kombinować ?"


A jeszcze mi się coś przypomniało czy jeżeli na sztywno określam z jakiego id pobieram czyli coś w tym stylu i służy mi to tylko do wyświetlenia tytułu z id=1:

  1. $query = mysql_query("SELECT * FROM strony WHERE id=1");
  2.  
  3. while($wynik=mysql_fetch_array($query)) {
  4.  
  5. echo $wynik['tytul'];
  6.  
  7. }


To też powinien robić to "WHERE id='1'" ?
nospor
Cytat
To też powinien robić to "WHERE id='1'" ?
NIe, nie powinieneś.... mysql za pomocą telepati połączy się z Twoim mózgiem i już samo będzie wiedziało że chcesz pobrać tylko rekordy z id=1....
Mega_88
Cytat(nospor @ 28.03.2013, 08:42:56 ) *
NIe, nie powinieneś.... mysql za pomocą telepati połączy się z Twoim mózgiem i już samo będzie wiedziało że chcesz pobrać tylko rekordy z id=1....


nospor wydaje mi się, że nie przeczytałeś całego tematu... Nie pytam o to jak pobrać rekord o id=1 tylko czy jeżeli już stosuję ten rodzaj zabezpieczenia "$id = mysql_real_escape_string($_GET['id']);"

To czy jak w id przekazuję stałą wartość, w przykładzie id=1 to mam to zrobić:

Tak id = '1' czy zostawić tak jak jest czyli id=1 żeby w jakimś stopniu zabezpieczyć się przed sql injection przez URL. Wydaje mi się, że nie muszę stałej wartości dawać w '1' bo nie otrzymuję jej od użytkownika.

Oczekuje odpowiedzi: lepiej będzie jak dasz w '' lub nie nie musisz.


p.s - wypowiedzi nie skomentuję.
viking
Opakowanie w '1' dało by ci tylko tyle że int byłby potraktowany jako string i baza rzucila by bledem.
Jesli stala wartosc nie musisz, wszystko co od uzytkownika juz tak.
Rozszerzenie mysql jes wycofywane z php.
nospor
Cytat
nospor wydaje mi się, że nie przeczytałeś całego tematu...
Zgadza się. Nie przeczytałem. Przepraszam.

Wracając do tematu:
wartosci liczbowych w ogóle się nie pakuje w żadne apostrofy, niezależnie czy idą od usera czy od ty to sobie sam z palca wpiszesz. Wartosci liczbowe to liczby a nie teksty. Tylko teksty bierze się w apostrofy.

Kolejna sprawa to to, że wartosci liczbowych nie przepuszcza się przez żadne mysql_escape_string, tylko rzutuje na liczbę:

$id = (int)$_GET['id'];
I tę wartosc można już spokojnie wkładać do zapytania.
Mega_88
Viking dziękuje za odpowiedź. Tak wiem, że już dawno czas na pdo, natomiast obecnie nie mam czasu, żeby się przesiąść i przerobić już gotową stronę.

Cytat(nospor @ 28.03.2013, 09:34:26 ) *
Zgadza się. Nie przeczytałem. Przepraszam.

Wracając do tematu:
wartosci liczbowych w ogóle się nie pakuje w żadne apostrofy, niezależnie czy idą od usera czy od ty to sobie sam z palca wpiszesz. Wartosci liczbowe to liczby a nie teksty. Tylko teksty bierze się w apostrofy.

Kolejna sprawa to to, że wartosci liczbowych nie przepuszcza się przez żadne mysql_escape_string, tylko rzutuje na liczbę:

$id = (int)$_GET['id'];
I tę wartosc można już spokojnie wkładać do zapytania.


Czyli jak dobrze zrozumiałem porponujesz, żeby zrobić to w ten sposób ?

  1. <?php
  2. if(isset($_GET['id'])) $id = $_GET['id']; else $id = 1;
  3. $id = (int)$_GET['id'];
  4. $query = mysql_query("SELECT * FROM strony WHERE id=$id");
  5. while($wynik=mysql_fetch_array($query)) {
  6. echo $wynik['tytul'];
  7. }
  8. ?>


Czyli zamiast:

  1. $id = mysql_real_escape_string($_GET['id']);
  2.  
  3. dać
  4.  
  5. $id = (int)$_GET['id']; , a WHERE id = '$id' dać WHERE id = id
  6.  


I wtedy mogę być w miarę spokojny o sql injection w URL typu www.domena.pl/index.php?id=1' ? Zaraz sobię to sprawdzę, ale jak Ty mi to jeszcze potwierdzisz to będę o wiele spokojniejszy smile.gif
nospor
Tak, dokładnie to proponuje smile.gif
Mega_88
Cytat(nospor @ 28.03.2013, 09:49:13 ) *
Tak, dokładnie to proponuje smile.gif


Sprawdziłem i chyba spełnia swoje zadanie przynajmniej już nie dostaję żadnych błedów po wpisaniu: www.domena.pl/index.php?id=1'

Dla potomnych może komuś się przyda:

  1. if(isset($_GET['id'])) $id = $_GET['id']; else $id = 1;
  2. $id = (int)$_GET['id'];
  3. $query = mysql_query("SELECT * FROM strony WHERE id=$id");
  4. while($wynik=mysql_fetch_array($query)) {
  5. echo $wynik['tytul'];
  6. }


A ostatnio spotkałem się z czymś takim

  1. darkmysqli16 ./darkmysqli16.py -u
  2. "http://domena.pl/index.php?aaaa&id=1+AND+1=2+UNION+SELECT+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,darkc0de,18
    ,19,20,21,darkc0de,23,24,25,26,darkc0de,28,29,30,31-


Czy takie zabezpieczenie jak zaproponowane przez nospor pozwoli się przed takimi zabiegami ochronić ? Czy to już wyższa półka i w jakiś inny sposób trzeba się bronić korzystając z mysql ?
nospor
Tak, to co napisałem zabezpiecza i przed czymś takim. Jakby tak nie było, to bym jak głupek tego ci nie pisał wink.gif

(int) rzutuje daną rzecz na liczbę. Niewazne czym jest dana rzecz - po rzutowaniu zawsze będzie liczbą. Tu nie ma żadnego hacka - liczba to liczba
Mega_88
Cytat(nospor @ 28.03.2013, 10:17:31 ) *
Tak, to co napisałem zabezpiecza i przed czymś takim. Jakby tak nie było, to bym jak głupek tego ci nie pisał wink.gif

(int) rzutuje daną rzecz na liczbę. Niewazne czym jest dana rzecz - po rzutowaniu zawsze będzie liczbą. Tu nie ma żadnego hacka - liczba to liczba


Dziękuje właśnie o to mi chodziło.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.