Czy jest gdzieś funkcja catchall, która działa dobrze w odkażaniu danych wejściowych użytkownika dla iniekcji SQL i ataków XSS, jednocześnie dopuszczając pewne typy tagów HTML?
php
security
xss
sql-injection
user-input
Brent
źródło
źródło
select * from users where name='$name'
, nie ma znaczenia, czy używasz PDO, MySQLi czy MySQL. Nadal jesteś w niebezpieczeństwie. Musisz użyć sparametryzowanych zapytań lub, jeśli musisz, użyć mechanizmów zmiany znaczenia na swoich danych, ale jest to o wiele mniej preferowane.Odpowiedzi:
Często nieporozumieniem jest to, że dane wejściowe użytkownika mogą być filtrowane. PHP ma nawet (obecnie przestarzałą) „funkcję”, zwaną magicznymi cytatami , która opiera się na tym pomyśle. To jest nonsens. Zapomnij o filtrowaniu (lub czyszczeniu lub jakkolwiek to nazywają ludzie).
To, co należy zrobić, aby uniknąć problemów, jest dość proste: za każdym razem, gdy osadzasz ciąg znaków w obcym kodzie, musisz uciec przed nim, zgodnie z regułami tego języka. Na przykład, jeśli osadzisz ciąg w jakimś SQL kierowanym do MySQL, w tym celu musisz uciec przed ciągiem za pomocą funkcji MySQL (
mysqli_real_escape_string
). (Lub, w przypadku baz danych, stosowanie przygotowanych instrukcji jest lepszym podejściem, jeśli to możliwe.)Innym przykładem jest HTML: jeśli osadzasz ciągi znaków w znacznikach HTML, musisz uciec przed nim
htmlspecialchars
. Oznacza to, że każda pojedyncza instrukcjaecho
lubprint
instrukcja powinna być używanahtmlspecialchars
.Trzecim przykładem mogą być polecenia powłoki: jeśli zamierzasz osadzić ciągi (takie jak argumenty) w poleceniach zewnętrznych i wywołać je za pomocą
exec
, musisz użyćescapeshellcmd
iescapeshellarg
.I tak dalej i tak dalej ...
Jedyny przypadek, w którym trzeba aktywnie filtrowanie danych, jeśli jest przyjmowanie Preformatowany wejście. Na przykład, jeśli pozwolisz swoim użytkownikom publikować znaczniki HTML, które planujesz wyświetlać w witrynie. Należy jednak rozsądnie unikać tego za wszelką cenę, ponieważ bez względu na to, jak dobrze go filtrujesz, zawsze będzie to potencjalna dziura w zabezpieczeniach.
źródło
mysql_real_escape_string
jest przestarzałe. Obecnie dobrą praktyką jest używanie przygotowanych instrukcji, aby zapobiec wstrzykiwaniu SQL. Więc przełącz się na MySQLi lub PDO.Nie próbuj zapobiegać iniekcji SQL poprzez odkażanie danych wejściowych.
Zamiast tego nie zezwalaj na wykorzystywanie danych podczas tworzenia kodu SQL . Użyj przygotowanych instrukcji (tj. Używając parametrów w zapytaniu szablonowym), które korzystają ze zmiennych powiązanych. Jest to jedyny sposób na zabezpieczenie przed wstrzyknięciem SQL.
Więcej informacji na temat zapobiegania wstrzykiwaniu SQL można znaleźć na mojej stronie http://bobby-tables.com/ .
źródło
Nie. Nie można generalnie filtrować danych bez kontekstu, do czego one służą. Czasami chcesz wziąć zapytanie SQL jako dane wejściowe, a czasem HTML jako dane wejściowe.
Musisz filtrować dane wejściowe na białej liście - upewnij się, że dane są zgodne z pewną specyfikacją tego, czego oczekujesz. Następnie musisz uciec przed użyciem, w zależności od kontekstu, w którym go używasz.
Proces ucieczki danych dla SQL - aby zapobiec wstrzykiwaniu SQL - bardzo różni się od procesu ucieczki danych dla (X) HTML, aby zapobiec XSS.
źródło
PHP ma teraz nowe fajne funkcje filter_input, które na przykład uwalniają cię od szukania „ostatecznego wyrażenia regularnego e-mail” teraz, gdy istnieje wbudowany typ FILTER_VALIDATE_EMAIL
Moja własna klasa filtrów (wykorzystuje JavaScript do wyróżnienia błędnych pól) może zostać zainicjowana przez żądanie ajax lub zwykły formularz. (patrz przykład poniżej)
Oczywiście należy pamiętać, że należy wykonać także ucieczkę zapytania SQL w zależności od używanego typu bazy danych (mysql_real_escape_string () jest na przykład bezużyteczny dla serwera SQL). Prawdopodobnie chcesz obsłużyć to automatycznie na odpowiedniej warstwie aplikacji, takiej jak ORM. Ponadto, jak wspomniano powyżej: do wysyłania do html użyj innych funkcji dedykowanych php, takich jak htmlspecialchars;)
Rzeczywiste zezwolenie na wprowadzanie HTML z podobnymi klasami i / lub znacznikami zależy od jednego z dedykowanych pakietów sprawdzania poprawności xss. NIE PISUJ SWOICH WŁASNYCH REGEXESÓW DO SKŁADANIA HTML!
źródło
Nie, nie ma.
Po pierwsze, wstrzyknięcie SQL stanowi problem z filtrowaniem danych wejściowych, a XSS jest wyjściem unikającym danych wyjściowych - abyś nawet nie wykonał tych dwóch operacji w tym samym czasie w cyklu życia kodu.
Podstawowe zasady praktyczne
mysql_real_escape_string()
)strip_tags()
do filtrowania niechcianego kodu HTMLhtmlspecialchars()
danymi wyjściowymi i pamiętaj o drugim i trzecim parametrze tutaj.źródło
Aby rozwiązać problem XSS, spójrz na HTML Purifier . Jest dość konfigurowalny i ma przyzwoitą historię.
Jeśli chodzi o ataki typu SQL injection, sprawdź dane wejściowe użytkownika, a następnie uruchom je za pomocą mysql_real_escape_string (). Ta funkcja nie pokona jednak wszystkich ataków polegających na wstrzyknięciu, dlatego ważne jest, aby sprawdzić dane przed zrzuceniem ich do ciągu zapytania.
Lepszym rozwiązaniem jest użycie przygotowanych wyciągów. Biblioteki PDO oraz mysqli rozszerzenie wsparcia nich.
źródło
PHP 5.2 wprowadziło funkcję filter_var .
Obsługuje wiele filtrów SANITIZE, VALIDATE.
http://php.net/manual/en/function.filter-var.php
źródło
Jedną sztuczką, która może pomóc w konkretnych okolicznościach, w których masz stronę podobną do
/mypage?id=53
i używasz id w klauzuli WHERE, jest upewnienie się, że id zdecydowanie jest liczbą całkowitą, tak jak:Ale oczywiście eliminuje to tylko jeden konkretny atak, więc przeczytaj pozostałe odpowiedzi. (I tak, wiem, że powyższy kod nie jest świetny, ale pokazuje konkretną obronę.)
źródło
$id = (int)$_GET['id']
i$que = sprintf('SELECT ... WHERE id="%d"', $id)
jest też dobryUżywaj nowoczesnych wersji MySQL i PHP.
Ustaw jawnie zestaw znaków:
Używaj bezpiecznych zestawów znaków:
Użyj funkcji przestrzennej:
PDO :: quote () - umieszcza cudzysłowy wokół ciągu wejściowego (jeśli jest wymagany) i zmienia znaki specjalne w ciągu wejściowym, używając stylu cytowania odpowiedniego dla sterownika:
Instrukcje przygotowane przez PDO : instrukcje przygotowane przez MySQLi obsługują więcej sterowników baz danych i nazwane parametry:
mysql_real_escape_string[przestarzałe w PHP 5.5.0, usunięte w PHP 7.0.0].Sprawdź, czy zmienna zawiera to, czego oczekujesz:
Użyj funkcji filtrowania filter_var () - filtruje zmienną o określonym filtrze:
więcej predefiniowanych filtrów
źródło
Opisujesz tutaj dwa osobne problemy:
1) Należy zawsze zakładać, że dane wprowadzone przez użytkownika są złe.
Używanie przygotowanych instrukcji lub filtrowanie za pomocą mysql_real_escape_string jest zdecydowanie koniecznością. PHP ma również wbudowane filter_input, co jest dobrym miejscem do rozpoczęcia.
2) Jest to duży temat i zależy od kontekstu danych wyjściowych. W przypadku HTML istnieją rozwiązania takie jak htmlpurifier. jako ogólna zasada, zawsze unikaj wszystkiego, co wysyłasz.
Oba problemy są o wiele za duże, aby je omówić w jednym poście, ale istnieje wiele postów, które są bardziej szczegółowe:
Metody Wyjście PHP
Bezpieczniejsze wyjście PHP
źródło
Jeśli korzystasz z PostgreSQL, dane wejściowe z PHP można zmienić za pomocą pg_escape_string ()
Z dokumentacji ( http://php.net/manual/es/function.pg-escape-string.php ):
źródło
Nie ma żadnej funkcji catchall, ponieważ należy rozwiązać wiele problemów.
SQL Injection - Dzisiaj, ogólnie rzecz biorąc, każdy projekt PHP powinien używać przygotowanych instrukcji za pośrednictwem PHP Data Objects (PDO) jako najlepszej praktyki, zapobiegając błędom z błędnego cytatu, a także w pełni funkcjonalnego rozwiązania przeciwko iniekcji . Jest to również najbardziej elastyczny i bezpieczny sposób dostępu do bazy danych.
Sprawdź (Jedyny właściwy) samouczek PDO, aby uzyskać prawie wszystko, co musisz wiedzieć o PDO. (Szczere podziękowania dla najlepszego współtwórcy SO, @YourCommonSense, za ten wspaniały zasób na ten temat.)
XSS - dezynfekuj dane w drodze w ...
Oczyszczacz HTML istnieje już od dawna i jest ciągle aktywnie aktualizowany. Możesz go użyć do oczyszczenia złośliwych danych wejściowych, jednocześnie pozwalając na hojną i konfigurowalną białą listę tagów. Działa świetnie z wieloma edytorami WYSIWYG, ale w niektórych przypadkach może być ciężki.
W innych przypadkach, w których wcale nie chcemy akceptować HTML / JavaScript, ta prosta funkcja jest przydatna (i przeszedłem wiele kontroli w stosunku do XSS):
/* Prevent XSS input */ function sanitizeXSS () { $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); $_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST; }
XSS - dezynfekuj dane po wyjściu ... chyba że zagwarantujesz, że dane zostały odpowiednio zdezynfekowane przed dodaniem ich do bazy danych, musisz je zdezynfekować przed wyświetleniem ich użytkownikowi, możemy wykorzystać te przydatne funkcje PHP:
echo
lubprint
wyświetlasz wartości dostarczone przez użytkownika, używaj,htmlspecialchars
chyba że dane zostały odpowiednio zdezynfekowane, bezpieczne i mogą wyświetlać HTML.json_encode
to bezpieczny sposób na dostarczanie wartości dostarczanych przez użytkowników z PHP na JavascriptCzy wywołujesz zewnętrzne polecenia powłoki za pomocą
exec()
lubsystem()
funkcji, czy dobacktick
operatora? Jeśli tak, oprócz SQL Injection i XSS możesz mieć dodatkowe obawy dotyczące rozwiązania problemu przez użytkowników wykonujących złośliwe polecenia na twoim serwerze . Musisz użyć,escapeshellcmd
jeśli chcesz uniknąć całej komendy LUB,escapeshellarg
aby uniknąć pojedynczych argumentów.źródło
mb_encode_numericentity
jest omawiany whtmlspecialchars
linku na # 3 XSSNajłatwiejszym sposobem uniknięcia błędów w odkażaniu danych wejściowych i ucieczce danych jest użycie frameworka PHP takiego jak Symfony , Nette itp. Lub jego części (silnik szablonów, warstwa bazy danych, ORM).
Silnik szablonów, taki jak Twig lub Latte, ma domyślnie włączanie ucieczki danych wyjściowych - nie musisz rozwiązywać ręcznie, jeśli odpowiednio uciekłeś od danych wyjściowych w zależności od kontekstu (część strony HTML lub JavaScript).
Framework automatycznie odkaża dane wejściowe i nie należy używać zmiennych $ _POST, $ _GET lub $ _SESSION bezpośrednio, ale poprzez mechanizm taki jak routing, obsługa sesji itp.
A dla warstwy bazy danych (modelu) istnieją frameworki ORM, takie jak Doctrine, lub owijarki wokół PDO, takie jak Nette Database.
Możesz przeczytać więcej na ten temat tutaj - Co to jest struktura oprogramowania?
źródło
Chciałem tylko dodać, że jeśli chodzi o ucieczkę danych wyjściowych, jeśli użyjesz php DOMDocument do utworzenia pliku wyjściowego HTML, automatycznie ucieknie we właściwym kontekście. Atrybut (wartość = "") i tekst wewnętrzny <span> nie są równe. Aby zabezpieczyć się przed XSS, przeczytaj to: OWASP XSS Prevention Cheat Sheet
źródło
Nigdy nie dezynfekujesz danych wejściowych.
Zawsze odkażasz wyjście.
Transformacje, które stosuje się do danych, aby można je było bezpiecznie uwzględnić w instrukcji SQL, są całkowicie różne od tych, które ubiegasz się o włączenie do HTML, są całkowicie różne od tych, o które wnioskujesz o włączenie do Javascript, są całkowicie różne od tych, o które ubiegasz się o włączenie do LDIF. zupełnie inne niż te, które stosuje się do włączenia do CSS, są całkowicie różne od tych, które stosuje się do włączenia do e-maila ...
Za wszelką cenę wejścia validate - zdecydować, czy należy przyjąć ją do dalszego przetwarzania lub poinformować użytkownika, że jest nie do przyjęcia. Ale nie stosuj żadnych zmian w reprezentacji danych, dopóki nie opuści ziemi PHP.
Dawno, dawno temu ktoś próbował wymyślić uniwersalny mechanizm dla wszystkich mechanizmów ucieczki danych, a my otrzymaliśmy „ magic_quotes ”, które nie poprawiły właściwie danych dla wszystkich celów wyjściowych i spowodowały, że instalacja wymagała innego kodu do działania.
źródło
Nigdy nie ufaj danym użytkownika.
W
trim()
usuwa białe znaki funkcyjne i inne predefiniowane znaki po obu stronach łańcucha.stripslashes()
Funkcja usuwa backslashyTa
htmlspecialchars()
funkcja przekształca niektóre predefiniowane znaki w encje HTML.Predefiniowane znaki to:
źródło
clean_input
? Dlaczego miałbyś chcieć usuwać ukośniki?Istnieje rozszerzenie filtra ( howto-link , manual ), które działa całkiem dobrze ze wszystkimi zmiennymi GPC. Nie jest to jednak magiczne zrób to wszystko, nadal będziesz musiał z niego korzystać.
źródło