Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Kilka pytań odnośnie bezpieczeństwa i filtracji danych.
Forum PHP.pl > Forum > Przedszkole
arkos
Witajcie, mam kilka pytań odnośnie bezpieczeństwa, w PHP i filtracji danych.
Od razu powiem na wstępnie, że przeczytałem całą książkę: "PHP5 Bezpieczne programowanie J.Ross, wydawnictwa Helion", oraz wiele wiele stron poświęconych bezpieczeństwu. Ale kto pyta nie błądzi smile.gif

A więc moje pierwsze pytanie, może trochę głupie no ale...:
Przycisk wysyłający formularz, i po którym jest sprawdzane w PHP, czy został wsyłany:
  1. <input type="submit" name="register" value="Zarejestruj się">

Sprawdzanie, w PHP:
  1. if(isset($_POST['register'])){ echo 'Akcje po wysłaniu'; }

Czy takie coś jest bezpieczne, czy w taki sposób ktoś może wstrzyknąć tutaj jakiś kod, czy muszę jeszcze jakoś zmienną $_POST['register'] filtrować?

Przy każdym wysyłaniu formularza sprawdzam dane, w taki sposób:
  1. $login = $_POST['login'];
  2. $pass = $_POST['pass'];
  3. $pass2 = $_POST['pass2'];
  4. if(!isset($login)) { info_blad('Podaj login'); }
  5. elseif(!preg_match('/^[0-9a-zA-Z_]*$/i', $login)){ info_blad('Błędne znaki w loginie!'); }
  6. elseif(strlen($login)<5) { info_blad('Podaj dłuższy login'); }
  7. elseif(strlen($login)>50) { info_blad('Podaj krótszy login'); }
  8. elseif(num_rows('`users` WHERE `login`="'.$login.'"') >= 1) { info_blad('Login jest zajęty); }
  9.  
  10. elseif(!isset($pass)) { info_blad('Podaj hasło'); }
  11. elseif(!preg_match('/^[0-9a-zA-Z!@#%^&*()-_=+,.]*$/i', $pass)){ info_blad('Błędne znaki w haśle'); }
  12. elseif(strlen($pass)<6) { info_blad('Podaj dłuższy login'); }
  13. elseif(strlen($pass)>50) { info_blad('Podaj krótszy login'); }
  14. elseif($pass!=$pass2) { info_blad('Hasła się nie zgadzają'); }
  15. ....
  16. else{ echo 'akcje po poprawnym sprawdzeniu danych, dodanie do bazy'; }

Czy sprawdzanie takie jest zarówno bezpieczne jak i również optmalne pod względem wydajności, taki typ stosuję w każdym formularzu na stronie, a jest ich sporo.

A może napisać jakąś klasę do usprawnienia tego procesu, niestet z klasami niezabardzo daję sobie radę?
Tak, aby dane były sprawdzane, np. w taki sposób:
  1. $sprawdz = new post_sprawdz();
  2. $sprawdz_dane -> liczby = $_POST['numer_domu']; // komunikat o ew. błędzie
  3. $sprawdz_dane -> znaki_az = $_POST['imie']; // komunikat o ew. błędzie
  4. itd.
  5. // jeżeli wszystko się zgadza
  6. echo 'akcje dodania danych do bazy, np.';


Pozdrawiam, i liczę na Wasze rady i propozycje smile.gif
ActivePlayer
1. przed wstawieniem danych do bazy użyj mysql_escape_string
2. przy pobieraniu danych z bazy filtruj wszystkie parametry (głównie te, które pobierasz z geta/posta), używając mysql_escape_string, rzutowania danych oraz ich walidacji
3. przy wyświetlaniu na stronie danych wpisanych przez użytkowników zawsze używaj htmlentities lub strip_tags, aby nikt nie wstrzyknął Ci swojego kodu javascript na stronę

imho to są 3 najważniejsze sprawy, związane z bezpieczeństwem.

w Twoim przypadku to "'`users` WHERE `login`="'.$login.'"'" jest potencjalnie niebezpieczne. wyobraź sobie że w $login masz wpisane
Kod
1' OR 1='1
arkos
ActivePlayer, z góry dzięki za odpowiedź.

Tak, oczywiście te aspekty znam. Wpisałem tak jak napisałeś: mojlogin_istniejacy_juz_w_bazie' OR 1='1
To zapytanie nie przejdzie ponieważ validator go nie przepuści, w powyższym formularzu, chyba że się mylę i działa to w inny sposób?

Dodatkowo pisząc tutaj o javascript i wstrzyknięciu kodu nasuwa mi się już pewne zagadnienie.
Przypuśćmy, że wyświetlę:
  1. echo $_GET['dane'];

Dodatkowo, w PHP, np. wyłączone jest dodawanie \ przed ' oraz " (czy przy włączonym uniemożliwi to, czy tylko utrudni?).
Ktoś sobie "wstrzyknie" javascript. To się wyświetli u niego w przeglądarce tylko i wyłącznie, więc jaki to ma skutek?
Przecież X użytkownikowi "wstrzyknięty" kod się nie wyświetli. Zresztą poco mu takie wstrzykiwanie, łatwiej użyć: Konsoli dla programistów, np. w Google Chrome.

Mam jeszcze jedno pytanie, czy można podać dane, w jakiś inny sposób niż jako tekst, np. w GET? Np, w jakimś kodzie HEXowym, czy innym, wtedy "uniknie się" dodania back shlesh przed ' lub " co znacznie zwiększa niebezpieczeństwo?

PS. Liczę również na odpowiedź na pytania zawarte w pierwszym poście.
wNogachSpisz
W zależności jakich danych oczekuje, robie to tak:

dla stringa:
  1. if ( ! isset($_REQUEST['var']) OR ! is_string($_REQUEST['var']) OR '' === $_REQUEST['var'] ) {
  2. die('invalid input');
  3. }


dla inta:
  1. if ( ! isset($_REQUEST['var']) OR ! is_string($_REQUEST['var']) OR ! ctype_digit($_REQUEST['var'])) {
  2. die('invalid input');
  3. }


Na tym kończę pierwszy etap walidacji, kolejne etapy są zależne od tego w jaki sposób chce przetwarzać input. Może on np. trafić do bazy, albo do HTML'a. Ważne aby nie przesadzić, pozwolić aplikacji się po chichu wysypać zamiast obsesyjnie walidować pod każdym możliwym katem, bo to kosztuje.
arkos
Dzięki.
Czekam dalej na propozycje i odpowiedzi. smile.gif

Zadaję te pytania, ponieważ kiedyś ktoś koledze skopiował całą stronę (wraz z plikami .php i umieścił u siebie).
A to nie było napewno zrobione przez FTP, a uploadu plików żadnego tam niemiał, a cały system był pisany autorsko, dodatkowo miał częste włamania do bazy.
A portal niebył to jakiś pierwszy lepszy, tylko z dużą ilością unikalnych wejść.
Daimos
Cytat(wNogachSpisz @ 11.02.2012, 19:31:46 ) *
(...) Ważne aby nie przesadzić, pozwolić aplikacji się po chichu wysypać zamiast obsesyjnie walidować pod każdym możliwym katem, bo to kosztuje.

No tutaj można by polemizować, lepiej dać się aplikacji po cichu wysypać? Powiedz to zleceniodawcy, który wpuści takich użytkowników do serwisu, że to ciche wysypanie nastąpi po 5min od wrzucenia produkcyjnej wersji wink.gif
Co do walidacji, to zgadzam się, że wszystko zależy co z tymi danymi będzie ktoś tworzył. Jeśli chodzi o stringi wrzucane do bazy, wystarczy zadbać o odpowiednie quoty (w stringu i dookoła;) )
Jeśli chodzi o int, może to nie jest świetne rozwiązanie, ale ja sam waliduję je w bardzo prosty sposób:
  1. if(!$parametrInt = (int) $zmiennaZawierajacaPrzeslaneDane)
  2. {
  3. // blad, chyba że system obslugiwac ma wartosci 0, wtedy caly warunek można odpuścić i wystarczy samo castowanie
  4. }

wNogachSpisz
Cytat(Daimos @ 11.02.2012, 22:55:49 ) *
No tutaj można by polemizować, lepiej dać się aplikacji po cichu wysypać? Powiedz to zleceniodawcy, który wpuści takich użytkowników do serwisu, że to ciche wysypanie nastąpi po 5min od wrzucenia produkcyjnej wersji wink.gif

Nie zrozumiałeś, a na domiar złego posłużyłeś się wynaturzonym przykładem. "Ciche wysypanie" to oczywiście uproszczenie, chodzi o to, że wiele systemów jak np. baza danych przeprowadzi własną walidację i często bardziej opłaca się "złapać" błąd zwrócony przez moduł który i sprawdzi dane o ile nie masz wpływu na to zachowanie. W przeciwnym razie aplikacja jest do dupy na wiele sposobów, nieproszony nie będę ich opisywał.

Cytat(Daimos @ 11.02.2012, 22:55:49 ) *
Jeśli chodzi o int, może to nie jest świetne rozwiązanie, ale ja sam waliduję je w bardzo prosty sposób:
  1. if(!$parametrInt = (int) $zmiennaZawierajacaPrzeslaneDane)
  2. {
  3. // blad, chyba że system obslugiwac ma wartosci 0, wtedy caly warunek można odpuścić i wystarczy samo castowanie
  4. }

To za mało, gdy wartość nie jest zadeklarowana zwrócony zostanie ERROR_NOTICE, a do tego nie można dopuścić.
wNogachSpisz
Cytat(desavil @ 12.02.2012, 12:38:50 ) *
Może jeszcze ktoś odpisać na moje inne pytania zadane powyżej smile.gif

Które? Te o włamaniach? A co my wróżbici? Skąd mamy wiedzieć jak ktoś się włamał mając zero informacji o incydencie :/
arkos
Ok, dzięki. Już się nauczyłem jak sprawdzać inita hehe smile.gif
Może jeszcze ktoś odpisać na moje inne pytania zadane powyżej. biggrin.gif

Mianowicie o:
1. Issecie, czy jest bezpieczne to, czy musze jeszcze filtrować jak tylko sprawdzam czy istnieje.
2. Czy moje sprawdzanie jest dobre pd względem wydajności.
3. Klasa/funkcja na uprawnienie sprawdzania jeżeli formularzy jest wiele.
4. Pytanie odnośnie \' oraz \"
5. Pytanie odnośnie innego systemu znaków
6. Pytanie o javascript

Jeżeli chodzi o włamanie tego typu do bazy lub kradzież plików, to pytanie jak tego mógł dokonać, bo zapytaniem do bazy danych raczej nie... (kradzież plików). Pytam z aspektów czysto bezpieczeństwa i zabezpieczenia się przed tym, aby nie popełnić jakiś błędów aż takiego typu, a nie ze względów hakerskich.

Wszystko to jest wyżej w postach napisane, a tutaj uzyskałem tak naprawdę odpowiedź na jedno pytanie.

smile.gif

Udzieli ktoś odpowiedzi na moje pytania?
wNogachSpisz
1. Nie rozumiem pytania.
2. To zależy.
3. Nie rozumiem pytania.
4. Powtórz pytanie.
5. Powtórz pytanie.
6. Powtórz pytanie.
arkos
Jak mam powtarzać, jak wszystko jest w pierwszym poście: http://forum.php.pl/index.php?showtopic=19...mp;#entry939257
oraz: http://forum.php.pl/index.php?showtopic=19...mp;#entry939268
wNogachSpisz
Chętnie odpowiem na każde pytanie. Problem w tym że nie chce mi się ich odcedzać. Potem powiesz że nie o to Ci chodziło. Szkoda mojego czasu.
arkos
W takim razię napiszę je jeszcze raz:

1. Pytanie:
Przycisk wysyłający formularz, i po którym jest sprawdzane w PHP, czy został wsyłany:
  1. <input type="submit" name="register" value="Zarejestruj się">

Sprawdzanie, w PHP:
  1. if(isset($_POST['register'])){ echo 'Akcje po wysłaniu'; }

Czy taka metoda jest bezpieczna, jeżeli sprawdzam tylko isset, i nic ze zmienną później nie robię, to czy muszę ją filtrować, w jakiś sposób.


2. Pytanie:
magic_quotes - w nowszej wersji ma zostać usunięty, więc muszę dodawać do wszystkich $_POST, $_GET - addslashes (oprócz np. jeżeli sprawdzam tylko isset, zależne od odpowiedzi na pierwsze pytanie)?


3. Pytanie:
Czy można podać dane, w jakiś inny sposób niż jako tekst, np. w GET? Np, w jakimś kodzie HEXowym, czy innym, wtedy "uniknie się" dodania back shlesh przed ' lub " co znacznie zwiększa niebezpieczeństwo?


4. Pytanie:
Ktoś sobie "wstrzyknie" javascript. To się wyświetli u niego w przeglądarce tylko i wyłącznie, więc jaki to ma skutek?
Przecież X użytkownikowi "wstrzyknięty" kod się nie wyświetli. Zresztą poco mu takie wstrzykiwanie, łatwiej użyć: Konsoli dla programistów, np. w Google Chrome.

5. Pytanie:
Jeżeli chodzi o włamanie do bazy lub kradzież plików, to pytanie jak tego mógł dokonać, bo zapytaniem do bazy danych raczej nie... (kradzież plików). Pytam z aspektów czysto bezpieczeństwa i zabezpieczenia się przed tym, aby nie popełnić jakiś błędów aż takiego typu, a nie ze względów hakerskich.

6. Pytanie:
Jakie proponujecie najlepsze rozwiązanie, jeżeli dałbym możliwość edycji plików html, php z poziomu strony.
Chodzi mi tutaj o wyświetlanie kodu do edycji oraz dodawanie kodu do bazy.
wNogachSpisz

1. W tej zmiennej może być wszystko, np. tablica z potężną ilością elementów lub wielka tablica wielowymiarowa. Mogą tam się znaleźć dowolne dane binarne, albo pusty ciąg znaków. O ile nie masz zamiaru używać danych z $_POST[‘register’] oraz masz pewność ze nigdzie w skrypcie nie użyjesz niezadeklarowanej zmiennej $register (patrz register_globals vuln). To powinieneś być bezpieczny.
2. Po co dodawać addslashes? Ja robie dokładnie w druga stronę, odwracam zniszczenia jakie poczynia magic_quotes jeśli jest włączone:
  1. function stripslashes_array(&$array, $iterations=0) {
  2. if ($iterations < 3) {
  3. foreach ($array as $key => $value) {
  4. if (is_array($value)) {
  5. stripslashes_array($array[$key], $iterations + 1);
  6. } else {
  7. $array[$key] = stripslashes($array[$key]);
  8. }
  9. }
  10. }
  11. }
  12.  
  13. stripslashes_array($_GET);
  14. stripslashes_array($_POST);
  15. stripslashes_array($_COOKIE);
  16. }

Wychodze z założenia, że chce mieć dane dokładnie w takiej formie w jakiej zostały wysłane przez użytkownika, sam decyduje jak trzeba się z nimi obejść, nie pozostawiam tego ustawieniom php.ini.
3. Nie rozumiem, rozwiń.
4. Może mieć różne przykre konsekwencje, może podesłać adres takiej strony komuś kto ma na Twojej stronie konto i je przejąć.
5. To zależy na jakich uprawnieniach działa baza, jeśli na root to można tworzyć pliki zapytaniem. Zabezpiecz się przez SQL injection np. używając ActiveRecords.
6. To na prawdę zależy, musiałbyś przedstawić wszystkie założenia projektu.
arkos
Nie rozumiem odpowiedzi na 4 pytanie.
Jeżeli on wtrzyknie taki kod to wstrzyknie go tylko u siebie, przecież nie zapiszego go u mnie na serwerze - musiałby edytować pliki.
wNogachSpisz
Jeśli wstrzyknie w URL, to może taki adres komuś podesłać i wykonać go w przeglądarce tego kogoś.
arkos
Ok, to byłoby na tyle myślę.

Dzięki, jak coś mi się kiedyś przypomni, napiszę w tym temacie.

Tak, wiem niezły odkop na forum. biggrin.gif Ale jednak coś mi się jeszcze przypomniało.

Czy w jakiś sposób (jeżeli chodzi o wynik końcowy) różni się wykonanie funkcji stripslashes_array przedstawionej przez wNogachSpisz (Post #14) od następującego zapisu?:
  1. $_GET = array_map('stripslashes', $_GET);
  2. $_POST = array_map('stripslashes', $_POST);
  3. $_COOKIE = array_map('stripslashes', $_COOKIE);
  4. }


Dzięki za pomoc!
com
nie, a w zasadzie tamto było troche wymyślaniem koła na nowo.. tylko magic_quotes zniknęło już z PHP
arkos
Cytat(com @ 27.04.2014, 19:14:05 ) *
nie, a w zasadzie tamto było troche wymyślaniem koła na nowo.. tylko magic_quotes zniknęło już z PHP

Dzięki, czyli będę używał wersji z array_map.
Tak, wiem że zniknęło już z PHP ale wolę jednak mieć, gdyby na jakimś serwerze była starsza wersja.
com
no tak, ale w specyfikacji masz określone, a od mq już dawno sie odchodziło, wiec rzadko to na serwerach było włączone.. a czasy addslashes już dawno przeminęły, poza tym teraz jest PDO i filtracja z jego poziomu w zupełności wystarcza..
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.