Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Bezpieczeństwo zmiennej GET
Forum PHP.pl > Forum > PHP
Ulysess
dzień dobry z góry mówię szukałem poprzez szukaj i nie znalazłem..
mam takie pytanie jakich funkcji użyć aby zabezpieczyć zawartość zmiennej tzn żeby nie było możliwe wykonanie jakiego kolwiek zapytania , złośliwego kodu.
w zmiennej get A oraz B mogą znajdować się tylko i wyłącznie liczby dodatnie. czy użycie is_numeric jest wystarczające questionmark.gif
Crozin
Możesz sprawdzić przy pomocy is_numeric, ctype_digit albo IMO najlepiej rzutować to na typ całkowity ((int) $abc), a następnie sprawdzić czy 0 < $abc < LIMIT_GÓRNY
wookieb
Cytat(Rookie @ 30.08.2009, 13:01:34 ) *
... Jest tylko jeden, z którego jakoś nie zrozumiałem za wiele.
Jak masz pomagać w taki sposób to po co się wgl za to bierzesz??
Szkoda, że na tym forum nie ma "rep -" albo "nie pomógł" albo jeszcze coś w tym stylu ...


http://php.net/is_numeric
http://php.net/abs
http://forum.php.pl/index.php?showtopic=30...stwo+skrypt%F3w
Ulysess
if(is_numeric(abs($_GET[a'])) && (is_numeric(abs($_GET['b']))))

próbowałem użyć abs ale to chyba nie przejdzie no chyba że w warunku nie zadziała
daniel1302
Tak, ja zawszę stosuje ctype_digit() ale ona rozpoznaje 0 jako false; ale is_numeric w zupełności wystarczy aby sprawdzić czy to jest liczba

if ($A < 0 && is_numeric($A))
{
}
Ulysess
Cytat(daniel1302 @ 30.08.2009, 13:37:16 ) *
Tak, ja zawszę stosuje ctype_digit() ale ona rozpoznaje 0 jako false; ale is_numeric w zupełności wystarczy aby sprawdzić czy to jest liczba

if ($A < 0 && is_numeric($A))
{
}

jeżeli w zmiennej dodasz minus też będzie akceptować więc nie za bardzo wysatrczy no chyba że po sprawdzeniu is numeric użyje ABS no to oki. przynajmniej tak mi się wydaje


ajc dopiero teraz zobaczyłem że uzywałeś czy jest wieksze od 0 sorki . hmm a nie lepiej tak jak ja powiedziałem hmm tylko is numeric a poźniej na wszelki wypadek abs ?
thek
Wszystko ładnie, pięknie, ale przez GET lecą także stringi a nie tylko int. Rozumiem, że w tym temacie akurat o INT chodzi, bo tak autor zadeklarował. Ja sądzę, że najpierw powinno być sprawdzenie czy zmienna jest w ogóle ustawiona (isset), potem sprawdzenie czy zmienna jest liczbą (is_numeric), a na sam koniec czy jest większa od 0. A dlaczego tak i w tej kolejności? To proste. w warunku IF php sprawdza zależności po kolei i w przypadku gdy wszędzie są AND przerwie sprawdzanie na pierwszym FALSE nie kończąc i idąc dalej. Wynika to z algebry Boole'a, gdyż tylko TRUE na wszystkich pozycjach daje TRUE. Wystarczy choć jeden FALSE i automatycznie całe wyrażenie jest FALSE. Dlatego powinno się te najbardziej istotne ustawiać na samym początku by warunki były jak najbardziej optymalne.
  1. if(isset($_GET['A']) && is_numeric($_GET['A']) && $_GET['A'] > 0 && isset($_GET['B']) && is_numeric($_GET['B']) && $_GET['B'] > 0 )

Może się w takim przypadku zdarzyć, że jeśli A nie będzie liczbą, to IF zwróci FALSE już przy drugim fragmencie i reszty nawet nie sprawdzi, wychodząc z warunku. To jest optymalizacja w IFie dla szybszego działania.
Inna sprawa to kolejność w jakiej sprawdzam. Dlaczego taką przyjąłem? To proste. Zmienna musi być i to chyba jasne dlaczego isset jest pierwsze. A dlaczego is_numeric jest drugie? Bo jeśli ktoś do zmiennej A wpisze c, t lub jakąkolwiek literę to $_GET['A'] zwróci TRUE. Wynika to z tego, że PHP niejawnie skonwertuje znak do odpowiadającego mu kodu ASCII i zwróci znak jako liczbę typu INT zawsze dodatnią, bo nie ma ujemnych znaków ASCII. A przecież to jest jawny błąd. Stąd sprawdzanie czy zmienna jest liczbą musi być wykonane wcześniej niż sprawdzenie większości od 0.
Crozin
Użycie is_numeric z reguły nie jest najlepszym rozwiązaniem - w końcu przepuszcza ono liczby w formacie wykładniczym, liczby zmiennoprzecinkowe jak i całkowite.
  1. <?
  2. $myVar = isset($_GET['myVar']) ? (int) /* albo (float) */ $_GET['myVar'] : 0;
  3. if($myVar <= 0 || $myVar > 123456){
  4. die('Invalid value');
  5. }
Dodatkowo taka zmienna ($myVar) jest już oczyszczona, tj. pozbawiona jest jakiś nadmiarowych plusów czy spacji.
Ulysess
ja to napisałem tak:
sprawdzam czy $a i $b jest pusta -> !empty
jeśli nie to sprawdza czy jest liczba - is_numeric
jeśli to to przepuści robie $a = abs($_GET['a'])

i dalej wykonanie dalszego skryptu. rozsądnie questionmark.gif
thek
Cytat(Crozin @ 30.08.2009, 14:52:54 ) *
Użycie is_numeric z reguły nie jest najlepszym rozwiązaniem - w końcu przepuszcza ono liczby w formacie wykładniczym, liczby zmiennoprzecinkowe jak i całkowite.
Prawda... Ale my sprawdzamy czy jest to liczba. Nie było napisane w pytaniu czy jest to liczba naturalna czy zmiennoprzecinkowa.Ja użyłem is_numeric by wyeliminować konwersję znaków do ich adpowiedników ASCII. I z tego ta funkcja się wywiązuje prawidłowo smile.gif
Fafu
IMO używanie
  1. $id = (int)$_GET['id'];

jest całkowicie wystarczające...
bełdzio
możesz też użyć wbudowanych filtrów, które w pełni spełnią Twoje wymogi => http://www.beldzio.com/phpowe-filtry
pyro
A jak nie filtr (np. wersja PHP starsza od 5.2.0) to wystarczy w zupełności rzutowanie typu + abs(). Jeżeli jednak chcesz sprawdzić, czy zmienna jest liczbowa (z GET) to np. można w ten sposób (samo is_int() nie wystarczy ze względu na to, że zmienne z ów tablic superglobalnych są stringami, przez co zwróci zawsze false).

  1. function is_string_integer($string)
  2. {
  3. return preg_match('|^[0-9]+$|', $string) ? true : false;
  4. }
Crozin
@pyro: pomijając to, że nie ma potrzeby dawania "? true : false", to... do czegoś takiego wyrażenia regularne? Przecież do sprawdzenia czy jest to liczba całkowita wystarczy ctype_digit() czy (int) $a == $a ? true : false;
pyro
Cytat(Crozin @ 30.08.2009, 21:01:18 ) *
@pyro: pomijając to, że nie ma potrzeby dawania "? true : false


preg_match zwraca false w przypadku błędu lub liczbę 1/0 jeśli znalazł/nie znalazł podanego wyrażenia. Ja po prostu dla wygody stosuje bool.

Cytat(Crozin @ 30.08.2009, 21:01:18 ) *
Przecież do sprawdzenia czy jest to liczba całkowita wystarczy ctype_digit()


Właśnie to chciałem napisać, ale odwróciłem się na chwilę do telewizora, obróciłem z powrotem i zapomniałem co miałem napisać biggrin.gif:D:D
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.