Jakie są najlepsze praktyki unikania ataków xss w witrynie PHP

Mam skonfigurowany PHP tak, że magiczne cytaty są włączone i rejestracja globals są wyłączone.

Robię co w mojej mocy, aby zawsze wywoływać htmlentities () dla wszystkiego, co robię, co pochodzi z wejścia użytkownika.

Od czasu do czasu przeglądam też moją bazę danych dla typowych rzeczy używanych w dołączonym xss, takich jak...

<script

Co jeszcze powinienem robić i jak mogę się upewnić, że rzeczy, które staram się robić, są zawsze zrobione.

Author: Rik Heywood, 2008-09-16

20 answers

Unikanie danych wejściowych nie jest najlepszym sposobem na skuteczne zapobieganie XSS. Również wyjście musi być ewakuowane. Jeśli używasz silnika szablonów Smarty, możesz użyć modyfikatora |escape:'htmlall' do konwersji wszystkich wrażliwych znaków na encje HTML(ja używam własnego modyfikatora |e, który jest aliasem do powyższego).

Moje podejście do bezpieczeństwa wejścia/wyjścia to:

  • przechowuje dane wejściowe użytkownika bez modyfikacji (bez HTML-u na danych wejściowych, tylko DB-aware za pomocą instrukcji przygotowanych przez PDO)
  • Ucieczka na wyjściu, w zależności od używanego formatu wyjściowego (np.]}
 58
Author: Michał Rudnicki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 11:41:23

Jestem zdania, że nie powinno się unikać niczego podczas wejścia, tylko na wyjściu. Ponieważ (przez większość czasu) nie można założyć, że wiesz, gdzie te dane idą. Na przykład, jeśli masz formularz, który pobiera dane, które później pojawiają się w wiadomości e-mail, którą wysyłasz, potrzebujesz innej interpretacji (w przeciwnym razie złośliwy użytkownik może przepisać nagłówki wiadomości e-mail).

Innymi słowy, możesz uciec tylko w ostatniej chwili, gdy dane "opuszczają" Twoją aplikację:

  • Lista pozycja
  • zapis do pliku XML, escape for XML
  • zapis do DB, escape (dla tego konkretnego DBMS)
  • napisz e-mail, escape dla e-maili
  • etc

Do skrótu:

  1. nie wiesz dokąd zmierzają Twoje dane
  2. dane mogą w rzeczywistości skończyć w więcej niż jednym miejscu, potrzebując różnych mechanizmów ucieczki, ale nie obu
  3. Dane uciekające dla niewłaściwego celu nie są naprawdę miłe. (Np. dostać maila z tematem "idź do Tommy\' s bar".)

Esp # 3 wystÄ ... pi, jeĹ "li usuniesz dane z warstwy wejĹ" ciowej (lub trzeba je ponownie usunÄ ... ć, itd.).

PS: popieram radę, żeby nie używać magic_quotes, to czyste zło!

 18
Author: Jilles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 21:32:29

Istnieje wiele sposobów na zrobienie XSS (Zobacz http://ha.ckers.org/xss.html ) i bardzo trudno go złapać.

Osobiście deleguję to do obecnego frameworka, którego używam (na przykład Code Igniter). Chociaż nie jest idealny, może złapać więcej niż moje ręcznie wykonane procedury kiedykolwiek zrobić.

 12
Author: Christian Studer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 11:38:17

To jest świetne pytanie.

Po pierwsze, nie unikaj tekstu przy wprowadzaniu, z wyjątkiem tego, aby był bezpieczny do przechowywania (np. do bazy danych). Powodem tego jest to, że chcesz zachować to, co zostało wprowadzone, aby móc kontekstowo prezentować je na różne sposoby i miejsca. Wprowadzenie zmian może zagrozić późniejszej prezentacji.

Kiedy przejdziesz do prezentacji danych odfiltruj to, czego nie powinno tam być. Na przykład, jeśli nie ma powodu, aby javascript tam być, wyszukaj go i usuń to. Łatwym sposobem na to jest użycie funkcji strip_tags i prezentowanie tylko tych znaczników html, na które zezwalasz.

Następnie weź to co masz i przekaż to htmlentities lub htmlspecialchars aby zmienić to co tam jest na znaki ascii. Zrób to w oparciu o kontekst i to, co chcesz wydostać.

Sugerowałbym również wyłączenie magicznych cytatów. Został usunięty z PHP 6 i uważa się, że korzystanie z niego jest złą praktyką. Szczegóły na http://us3.php.net/magic_quotes

Aby uzyskać więcej informacji sprawdź http://ha.ckers.org/xss.html

To nie jest pełna odpowiedź, ale mam nadzieję, że wystarczy, aby pomóc Ci zacząć.

 10
Author: Matt Farina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 12:13:45

Rikh Pisze:

Robię co w mojej mocy, aby zawsze wywoływać htmlentities () dla wszystkiego, co robię, co pochodzi z wejścia użytkownika.

Zobacz esej Joela na temat aby Kod wyglądał źle , aby uzyskać pomoc w tym

 7
Author: Mason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 19:13:19

Polegam na PHPTAL .

W Przeciwieństwie Do Smarty i zwykłego PHP, domyślnie ucieka od wszystkich danych wyjściowych. Jest to duża wygrana dla bezpieczeństwa, ponieważ Twoja strona nie stanie się vurnelable, jeśli zapomnisz htmlspecialchars() LUB |escape gdzieś.

XSS jest atakiem specyficznym dla HTML, więc wyjście HTML jest właściwym miejscem, aby temu zapobiec. Nie powinieneś próbować wstępnego filtrowania danych w bazie danych, ponieważ może być konieczne wyjście danych do innego medium, które nie akceptuje HTML, ale ma własne ryzyko.

 4
Author: Kornel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-25 21:07:32

Biblioteka szablonów. a przynajmniej tak powinny robić biblioteki szablonów. Aby zapobiec XSS wszystkie wyjścia powinny być zakodowane. To nie jest zadanie Głównej Logiki aplikacji / sterowania, powinno być obsługiwane wyłącznie metodami wyjściowymi.

Jeśli posypujesz htmlentities () swoim kodem, ogólny projekt jest zły. I jak sugerujesz, możesz przegapić jedno lub dwa miejsca. Dlatego jedynym rozwiązaniem jest rygorystyczne kodowanie html - > when output Vars get zapisany w strumieniu html / xml.

Niestety, większość bibliotek szablonów php dodaje tylko własną składnię szablonów, ale nie zajmują się kodowaniem wyjściowym, lokalizacją, walidacją html, czy czymkolwiek ważnym. Może ktoś jeszcze zna odpowiednią bibliotekę szablonów dla php?

 4
Author: user319490,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-18 02:01:08

Unikanie wszystkich danych wejściowych użytkownika jest wystarczające dla większości witryn. Upewnij się również, że identyfikatory sesji nie kończą się w adresie URL, aby nie mogły zostać skradzione z linku Referer do innej witryny. Dodatkowo, jeśli zezwalasz użytkownikom na przesyłanie linków, upewnij się, że żadne łącza protokołu javascript: nie są dozwolone; będą one uruchamiać skrypt, gdy tylko użytkownik kliknie link.

 2
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 11:24:39

Jeśli obawiasz się ataków XSS, kodowanie ciągów wyjściowych do HTML jest rozwiązaniem. Jeśli pamiętacie, aby zakodować każdy pojedynczy znak wyjściowy do formatu HTML, nie ma możliwości przeprowadzenia udanego ataku XSS.

Czytaj więcej: dezynfekcja danych Użytkownika: jak i gdzie to zrobić

 2
Author: Niyaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 11:40:58

Osobiście wyłączyłbym magic_quotes. W PHP5+ jest domyślnie wyłączony i lepiej kodować tak, jakby go nie było w ogóle, ponieważ nie ucieka od wszystkiego i zostanie usunięty z PHP6.

Dalej, w zależności od rodzaju filtrowanych danych użytkownika będzie dyktować co dalej np. jeśli jest to tylko tekst np. nazwa, to strip_tags(trim(stripslashes())); to lub do sprawdzenia zakresów użyj wyrażeń regularnych.

Jeśli oczekujesz pewnego zakresu wartości, Utwórz tablicę ważnych wartości i dopuszczaj tylko te wartości poprzez (in_array($userData, array(...))).

Jeśli sprawdzasz liczby, użyj is_numeric, aby wymusić liczby całkowite lub rzucić do określonego typu, co powinno zapobiec próbom wysyłania ciągów zamiast.

Jeśli masz PHP5. 2+, rozważ użycie filter () i użycie tego rozszerzenia, które może filtrować różne typy danych, w tym adresy e-mail. Dokumentacja nie jest szczególnie dobra, ale poprawia się.

Jeśli musisz obsługiwać HTML to powinieneś rozważ coś w rodzaju PHP Input Filter lub HTML Purifier. HTML Purifier będzie również sprawdzał poprawność HTML. Nie jestem pewien, czy filtr wejściowy jest nadal rozwijany. Oba pozwalają zdefiniować zestaw znaczników, które mogą być używane i jakie atrybuty są dozwolone.

Cokolwiek zdecydujesz, zawsze pamiętaj, nigdy przenigdy nie ufaj nic przychodzi do skryptu PHP od użytkownika (w tym siebie!).

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 19:09:23

Wszystkie te odpowiedzi są świetne, ale zasadniczo rozwiązaniem dla XSS będzie zaprzestanie generowania dokumentów HTML przez manipulację łańcuchami znaków.

Filtrowanie danych wejściowych jest zawsze dobrym pomysłem dla każdej aplikacji.

Unikanie wyjścia za pomocą htmlentities () i friends powinno działać tak długo, jak jest używane poprawnie, ale jest to HTML odpowiednik tworzenia zapytania SQL przez łączenie łańcuchów z mysql_real_escape_string ($var) - powinno działać, ale mniej rzeczy może potwierdzić twoją pracę, że tak powiem, w porównaniu do podejścia takiego jak używanie parametryzowanych zapytań.

Długoterminowym rozwiązaniem powinno być zbudowanie strony wewnętrznie przez aplikacje, być może przy użyciu standardowego interfejsu, takiego jak DOM, a następnie użycie biblioteki (takiej jak libxml) do obsługi serializacji do XHTML/HTML/etc. Oczywiście, jesteśmy daleko od tego, że jest popularny i wystarczająco szybko, ale w międzyczasie musimy budować nasze dokumenty HTML za pomocą operacji ciągów, a to z natury bardziej ryzykowne.

 2
Author: Daniel Papasian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 21:24:32

Uważam, że korzystanie z tej funkcji pomaga usunąć wiele możliwych ataków xss: http://www.codebelay.com/killxss.phps

 2
Author: barce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 21:35:01

"magiczne Cytaty" to paliatywne lekarstwo na niektóre z najgorszych wad XSS, które działa poprzez unikanie wszystkiego na wejściu, czegoś, co jest złe z założenia. Jedynym przypadkiem, w którym ktoś chciałby go użyć, jest to, że absolutnie musisz użyć istniejącej aplikacji PHP, o której wiadomo, że została napisana beztrosko w odniesieniu do XSS. (W tym przypadku masz poważne kłopoty nawet z "magicznymi cytatami".) Podczas tworzenia własnej aplikacji należy wyłączyć "magiczne cytaty" i stosować bezpieczne praktyki XSS zamiast tego.

XSS, luka w skryptach między stronami, występuje, gdy aplikacja zawiera ciągi z zewnętrznych źródeł (dane wejściowe użytkownika, pobrane z innych stron internetowych, itp.) W [x]HTML, CSS, ECMAscript lub innym pliku wyjściowym analizowanym przez przeglądarkę, bez odpowiednich znaków specjalnych, w nadziei, że znaki specjalne, takie jak less-than (w [X] HTML), pojedyncze lub podwójne cudzysłowy (ECMAscript) nigdy się nie pojawią. Właściwym rozwiązaniem jest zawsze escape string zgodnie z regułami języka wyjściowego: używanie encji w [X]HTML, ukośniki w ECMAscript itp.

Ponieważ może być trudno śledzić to, co jest niezaufane i musi być zabezpieczone, dobrym pomysłem jest zawsze unikanie wszystkiego, co jest " ciągiem tekstowym "w przeciwieństwie do" tekstu ze znacznikami " w języku takim jak HTML. Niektóre Środowiska programistyczne ułatwiają to, wprowadzając kilka niekompatybilnych typów łańcuchów: "string" (zwykły tekst)," HTML string " (znaczniki HTML) i tak dalej. W ten sposób bezpośrednia konwersja z "string" na "HTML string" byłaby niemożliwe, a jedynym sposobem, w jaki łańcuch znaków może stać się znacznikiem HTML, jest przekazanie go przez funkcję ucieczki.

"Register globals", choć wyłączenie go jest zdecydowanie dobrym pomysłem, rozwiązuje problem zupełnie inny niż XSS.

 2
Author: Alexey Feldgendler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-11 15:48:44

Twórz pliki cookie sesji (lub wszystkie pliki cookie), których używasz HttpOnly. W takim przypadku większość przeglądarek ukryje wartość pliku cookie przed JavaScript. Użytkownik może nadal ręcznie kopiować pliki cookie, ale pomaga to zapobiec bezpośredniemu dostępowi do skryptów. StackOverflow miał ten problem podczas beta.

To nie jest rozwiązanie, tylko Kolejna cegła w ścianie

 1
Author: basszero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 12:17:07
  • nie ufaj wejściom użytkownika
  • Escape all free-text output
  • nie używaj magic_quotes; sprawdź, czy istnieje wariant DBMS-specfic, lub użyj PDO
  • rozważ używanie Plików cookie tylko HTTP, jeśli to możliwe, aby uniknąć złośliwego skryptu mogącego przechwycić sesję
 1
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 21:28:06

Powinieneś przynajmniej zweryfikować wszystkie dane trafiające do bazy danych. I spróbuj również zweryfikować wszystkie dane opuszczające bazę danych.

Mysql_real_escape_string jest dobry, aby zapobiec wtrysku SQL, ale XSS jest trudniejsze. Powinieneś preg_match, stip_tags lub htmlentities gdzie to możliwe!

 1
Author: Abeon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-19 23:54:53

Najlepszą obecnie metodą zapobiegania XSS w aplikacji PHP jest HTML Purifier (http://htmlpurifier.org/). jedną z drobnych wad jest to, że jest to dość duża biblioteka i najlepiej jest używać z pamięcią podręczną kodu op, taką jak APC. Możesz tego użyć w dowolnym miejscu, w którym niezaufana zawartość jest wysyłana na ekran. Jest to o wiele bardziej dokładne, że htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags, itp.

 1
Author: Night Owl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-24 18:36:55

Użyj istniejącej biblioteki sanityzacji wprowadzanej przez użytkownika, aby wyczyścić wszystkie dane wprowadzane przez użytkownika. Jeśli nie włożysz w to dużo wysiłku, samodzielne wdrożenie go nigdy nie zadziała.

 0
Author: dbr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 12:04:44

Uważam, że najlepszym sposobem jest użycie klasy, która pozwala powiązać kod, więc nie musisz się martwić o ręczne uciekanie danych.

 0
Author: Darren22,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 21:37:34

Trudno jest wdrożyć dokładne SQL injection / XSS injection prevention na stronie, która nie powoduje fałszywych alarmów. W CMS użytkownik końcowy może chcieć użyć <script> lub <object>, który łączy się z elementami z innej strony.

Polecam wszystkim użytkownikom zainstalować Firefoksa z NoScript ; -)

 -1
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-17 11:51:31