Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Całościowe filtrowanie danych
Forum PHP.pl > Forum > PHP
Kildyt
Cześć! smile.gif

Piszę aktualnie nowe jądro i chcę przy użyciu jeden funkcji przefiltrować dane pod wieloma względami (html, mysql itp.).

Poczytałem trochę na w internecie o filtrowaniu danych, nawet znalazłem bardzo prosty i zrozumiały wykres: link w .pdf.

Napisałem funkcję filter i wygląda ona tak:
  1. <?php
  2. function filter($give, $type) {
  3.    if (!$type OR is_string($type)) {
  4.        $error = new error;
  5.        
  6.        $error -> show('Nie podałeś typu zmiennej podczas filtrowania danych! 1 - string (tekst), 2 - int (liczba całkowita)', '1');
  7.    }
  8.    
  9.    if ($type == "2") {
  10.        $type = "is_int";
  11.    }
  12.    
  13.    if ($type == "1") {
  14.        $type = "is_string";
  15.    }
  16.    
  17.    
  18.    if ($type($give)) {
  19.        return $give;
  20.    } else {
  21.        $error = new error;
  22.        
  23.        $error -> show('Zawartość zmiennej różni się od jej typu! 1 - string (tekst), 2 - int (liczba całkowita)', '1');
  24.    }
  25. }
  26. ?>


Przykładowe zastosowanie funkcji to:
  1. <?php
  2. $title = filter($_GET['title'], 1);
  3. $id = filter($_GET['id'], 2);
  4. ?>


Spis zastosowanych funkcji do przefiltrowania zmiennej (w kolejności zastosowania): stripslashes, escapeshellcmd, strip_tags, htmlspecialchars, mysql_real_escape_string, urlencode.

Jak myślicie, czy ten skrypt jest poprawny? Zmienić szereg wykonywanych funkcji, może jakąś dodać, lub usunąć?
zimi
nie jestem sobie w stanie wyobrazić powodu dla którego potrzebowałbym zastosować taką funkcję...
każda funkcja którą użyłeś w łańcuchu jest przeznaczona do innego celu chyba że masz zamiar
pobrany z adresu ciąg wrzucić do bazy danych przetwarzając niebezpieczne znaki (względem XSS) na encje usuwając tagi (których nie będzie na skutek działania poprzedniej funkcji) uruchomić polecenie z konsoli wyrzucając przy okazji escape'owanie które dodałeś...

w skrócie ta funkcja nie ma sensu... no chyba że czegoś nie wiem... co ostatnio często się zdarza...

każdą z funkcji z łańcucha używasz w innym celu... jedną(z reguły) gdy chcesz usunąć znaki ucieczki dodane automatycznie przy odpowiednich ustawieniach PHP, drugą gdy chcesz coś odpalić z konsoli, dwie kolejne przeciw atakom XSS, piątą przeciw atakom na bazę danych, a szóstą aby adresy url były odpowiednio zakodowane

to że je sobie wszystkie połączysz nie znaczy że Twoja aplikacja będzie bezpieczna..., znaczy tylko że nie wiesz co napisałeś...
Kildyt
Chciałem napisać jedną funkcję dzięki, której będę filtrował dane pochodzące od użytkownika. Np. formularz rejestracji, wyszukiwanie itp. itd.

Nie mogę Cię trochę zrozumieć. Przecież dane pochodzące od użytkownika trzeba przefiltrować, a to, że dodałem wszystko do jednej funkcji to dla mnie oszczędzanie czasu, a w razie problemów zmienię tylko funkcję, a nie cały kod.
Niestety, ale kilka miesięcy temu miałem problem z atakiem XSS. Całe szczęście, że został dodany tylko kod javascript do kodu strony, ale i tak musiałem przefiltrować bazę danych. Od tego czasu wolę się ubezpieczyć i filtrować dane pod każdym względem.
zimi
może opisowo
w skrócie... nie ubezpieczasz domu od "kradzieży samochodu", ani samochodu "od katastrof budowlanych"

każda z funkcji którą użyłeś w łańcuchu swoich funkcji służy do innych operacji co już napisałem
jak chcesz wykorzystać dane w zapytaniach do bazy to bierzesz mysql_real_escape_string (i z reguły tylko tą!)
a jak chcesz użyć z polecenia exec, system etc. to używasz escapeshellcmd (i z reguły tylko tą!)
choć jestem sobie w stanie wyobrazić jak tego mógłbym użyć razem to nie ma to większego sensu

"ubezpieczasz" dane w swoim skrypcie od tego od czego są narażone..., a nie od wszystkiego niezależnie czym są i jak używasz...

Jeśli nadal nie rozumiesz to przeczytaj dokumentacje wszystkich funkcji które użyłeś... potem jeszcze raz moje odpowiedzi
a potem ew. przetestuj działanie kodu:
  1. <?php
  2. $zmienna = 'asdf"asdf';
  3. echo $zmienna = mysql_escape_string($zmienna);
  4. echo $zmienna = striplslashes($zmienna);
  5. ?>

i wyciągnij wnioski
szagi3891
Ja bym proponował inną funkcję. Przy założeniu że dane zapisane są w kodowaniu utf-8 i jeśli się trzymamy tego kodowania to warto było by sprawdzić czy tekst jest poprawnie zakodowany. Jakiś robot mógłby dodać syf do bazy bądź w czymś tam.

Funkcja którą proponuje sprawdza wpierw sekwencję utf-8 a w przypadku błędnej sekwencji podmienia ją na znak '?'
Entecje zamieniane są na znaki w odpowiednim kodowaniu natomiast tylko kilka znaków zawsze jest pozostawianych w postaci entecji. Oczywiści chodzi o znaki które pozostawione same sobie chciały by wejść w interakcję z naszym kodem.

  1. <?php
  2. function clear_text($dane) {
  3.    $UTF8_BAD =
  4.    '([x00-x7F]'.                          # ASCII (including control chars)
  5.    '|[xC2-haha.gifF][x80-xBF]'.               # non-overlong 2-byte
  6.    '|xE0[xA0-xBF][x80-xBF]'.           # excluding overlongs
  7.    '|[xE1-xECxEExEF][x80-xBF]{2}'.    # straight 3-byte
  8.    '|xED[x80-x9F][x80-xBF]'.           # excluding surrogates
  9.    '|xF0[x90-xBF][x80-xBF]{2}'.        # planes 1-3
  10.    '|[xF1-xF3][x80-xBF]{3}'.            # planes 4-15
  11.    '|xF4[x80-x8F][x80-xBF]{2}'.        # plane 16
  12.    '|(.{1}))';                              # invalid byte
  13.    
  14.    $temp = '';
  15.    
  16.    while (preg_match('/'.$UTF8_BAD.'/S', $dane, $matches))
  17.        {
  18.        if (!isset($matches[2]))
  19.            $temp .= $matches[0];
  20.        else
  21.            $temp .= '?';                                                        //zastępienie błednych sekwencji znakiem '?'
  22.            
  23.        $dane = substr($dane,strlen($matches[0]));
  24.        }
  25.        
  26.    $dane = $temp;
  27.    
  28.    
  29.    $dane = preg_replace('#[x00-x08x0bx0cx0e-x1f]#si', '', $dane);        //usunięcie znaków niewidocznych oprócz entera i tabulacji
  30.    $dane = preg_replace("#r\n?#", "\n", $dane);                                //znormalizowanie znaków nowej linii
  31.    
  32.    $dane = html_entity_decode($dane, ENT_QUOTES, "utf-8" );                     //usunięcie zbędnych entecji
  33.  
  34.    $dane = str_replace("&", "&amp;"   , $dane);                                //zabezpieczenie znaków niebezpiecznych
  35.    $dane = str_replace("<", "&lt;"    , $dane);
  36.    $dane = str_replace(">", "&gt;"    , $dane);
  37.    $dane = str_replace("'", "&apos;"  , $dane);
  38.    $dane = str_replace("`", "&acute;" , $dane);
  39.    $dane = str_replace('"', "&quot;"  , $dane);
  40.    return $dane;
  41.    }
  42. ?>


tam gdzie jest --- haha.gif --- powinny być dwa znaki : x 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.