2010-08-25 11 views
5

Obecnie dochodzę do siebie po paskudnym ataku XSS i zdałem sobie sprawę, że nigdy nie odkażałem danych wejściowych dotyczących kilku formularzy moja strona. Użyłem funkcji Znajdź w plikach Notepad ++ do wyszukiwania $_POST we wszystkich moich plikach PHP i uzyskałem prawie 5000 wyników. Teraz naprawdę nie chcę iść i ręcznie dodawać strip_tags do każdego z tych wyników, ale zamiana wszystkiego nie załatwiłaby ... i jestem totalnym noobem, jeśli chodzi o rzeczy takie jak wyrażenia regularne .

Czy jest jakiś sposób, aby uczynić to nieco mniej żmudnym?

Odpowiedz

2

można umieścić to w pliku (np safe.php)

foreach ($_POST as $key => $value) { 
    $_POST[$key] = is_array($key) ? $_POST[$key]: strip_tags($_POST[$key]); 
} 

Następnie umieścić require_once("safe.php"); w każdy każdego z plików php (lub plik, który cały swój pliku php już w komplecie)
To brzydki hack ... ale może zaoszczędzić twój czas.

+0

Awesome.Właśnie tego szukałem. –

+0

To nie zabezpieczy się przed XSS, gdy istnieją pola formularza, które mają nazwy takie jak 'foo [bar]' lub 'foo []', które PHP automatycznie konwertuje na tablice. – Tgr

+0

@Tgr: tak, to absolutnie nie powiedzie się tak jak powiedziałeś, ale myślę, że wpadł na pomysł, aby dostosować go do tego, czego potrzebuje – w00d

6

Hmm, myślę array_walk_recursive by rade:

function custom_strip(&$val, $index) { 
    $val = strip_tags($val); 
} 
array_walk_recursive($_POST, 'custom_strip'); 
0

bardzo prosta. Umieścić to na górze każdego pliku lub we wspólnym pliku nagłówka, która jest wywoływana na samym początku za każdym razem:

function mystriptag(&$item) 
{ 
    $item = strip_tags($item); 
} 

array_walk($_POST, mystriptag); 
+0

To nie będzie chronić przed XSS, gdy istnieją pola formularza, które mają nazwy takie jak 'foo [bar] lub 'foo []', który PHP automatycznie konwertuje na tablice. – Tgr

18

Wystarczy użyć array_map().

$Clean = array_map('strip_tags', $_POST); 

Albo jeśli chcesz wrócić do zmiennej $_POST:

$_POST = array_map('strip_tags', $_POST); 

To chyba lepszy pomysł chociaż użyć innej zmiennej i zmienić wszystkie wystąpienia $_POST do $Clean w plikach.

0

może po prostu array_mapstrip_tags do $_POST, ale jest o wiele ładniejszy napisać funkcję niestandardową do uzyskania z niego dane:

function post_data($name) { 
    global $post_cache; 
    if (in_array($name, $post_cache)) { 
     return $post_cache[$name]; 
    } 
    $val = $_POST[$name]; 
    if (is_string($val)) { 
     $val = strip_tags($val); 
    } else if (is_array($val)) { 
     $val = array_map('strip_tags', $val); 
    } 
    $post_cache[$name] = $val; 
    return $val; 
} 

Spowoduje to, że kod jest bardziej czytelny (inni patrząc na nią na ogół zakładamy że $_POST['foo'] to dane w polu formularza , a nie coś, co już zostało wstępnie przetworzone), nie spowoduje problemów z wtyczkami lub bibliotekami, które próbują uzyskać bezpośredni dostęp do $ _POST, ułatwia dodanie większej logiki do wstępnego przetwarzania $_POST (unescape, gdy magic quotes są włączone) bez polowania na całe miejsce s w kodzie, w którym korzystasz z danych POST, i oszczędzasz sobie ogromnych bólów głowy, gdy zdasz sobie sprawę, że istnieje kilka pól POST, w których potrzebujesz znaczników HTML. Ogólnie rzecz biorąc, jest naprawdę złym pomysłem bezpośrednia zmiana dowolnego z superglobałów.

Lepiej jest również odkażać dane na wyjściu, a nie na wejściu. Różne zastosowania wymagają różnych metod, na przykład, jeśli używasz

<div class="user_photo"> 
    <img src="<?php echo photo_path($user_id) ?>" alt="<?php echo $user_name ?>" /> 
</div> 

następnie $user_name jest ataku XSS i strip_tags nie pomaga przeciwko niej w ogóle; potrzebujesz htmlspecialchars. Jeśli dane użytkownika są używane jako adresy URL, potrzebna jest jeszcze jedna metoda ochrony przed adresami URL javascript: i tak dalej.