2015-03-11 9 views
7

Po kilku godzinach szukania błędów odkryłem przyczynę jednego z moich najbardziej irytujących błędów.Czy bezpieczne jest odblokowanie ampersand do wprowadzania danych przez użytkownika?

Kiedy użytkownicy wpisują mi wiadomość na mojej stronie, mogą ją tytułować za pomocą zwykłego tekstu i encji html.

Oznacza to, że w niektórych przypadkach użytkownicy będą wpisywać tytuły ze wspólnymi obrazami encji html, takimi jak ta twarz. (͡ ° ͜ʖ ͡ °).

Aby zapobiec wstrzykiwaniu html, używam htmlspecialchars(); na tytule i denerwująco przekształciłby obraz w jego format strony HTML po wyświetleniu na stronie później.

(͡° ͜ʖ ͡°) 

zdałem sobie sprawę, problem tutaj było to, że tytuł był zakodowany jako powyższym przykładzie, a htmlspecialchar, jak robi to, co chciałem i wtrysk kodowanie możliwe html, było obrócenie ampersanda w podmiotach do

&. 

Przez to, że nie uciekłem ze wszystkich amperandów i zmieniono je z powrotem na &, naprawiłem mój problem i twarz wyszła zgodnie z oczekiwaniami.

Jednak nie jestem pewien, czy jest to nadal bezpieczne przed złośliwym html. Czy bezpieczne jest dekodowanie ampersandów w tytułach przypisanych przez użytkownika? Jeśli nie, jak mogę rozwiązać ten problem?

+0

Jeśli twoje obiekty są wyświetlane jako tekst, prawdopodobnie dwa razy wywołasz 'htmlspecialchars()'. –

+0

@Marat. Kiedy POST pobierał wartość z wejścia, automatycznie kodował bardziej niejasne elementy, takie jak nos i usta twarzy, którą dostarczyłem. Jednak nie kodował on rzeczy takich jak cytaty lub ostre nawiasy. Więc to jest rzeczywiście mój problem, niektóre z encji są kodowane dwukrotnie. Niestety nie wiem, jak to naprawić, poza ponownym kodowaniem. Oto dlaczego zadałem to pytanie, aby sprawdzić, czy jest lepszy sposób. – Clint

+0

Takie automatyczne wyprowadzanie po stronie przeglądarki może wystąpić, jeśli strona zawierająca formularz używa przestarzałego jednobajtowego kodowania, takiego jak Windows-1252. Czy na pewno używasz Unicode (w szczególności UTF-8)? ;-) –

Odpowiedz

4

Jeśli twoje obiekty są wyświetlane jako tekst, prawdopodobnie dwa razy dzwonisz pod numer htmlspecialchars().

Jeśli nie wywołasz dwa razy jawnie numeru htmlspecialchars(), prawdopodobnie jest to automatyczne przejście po stronie przeglądarki, które może wystąpić, jeśli strona zawierająca formularz używa przestarzałego jednobajtowego kodowania, takiego jak Windows-1252. Taki automatyczny escaping jest jedynym sposobem poprawnego przedstawienia znaków nieobecnych w zestawie znaków określonego kodowania jednobajtowego. Wszystkie obecne przeglądarki (w tym Firefox, Opera i IE) robią to.

Upewnij się, że używasz kodowania Unicode (w szczególności UTF-8).

Aby użyć kodowania Unicode, dodaj element <meta charset="utf-8" /> do sekcji HEAD strony HTML zawierającej formularz. I nie zapomnij zapisać samej strony HTML w kodowaniu UTF-8. Aby używać Unicode w PHP, zwykle wystarczy użyć multibyte (mb_ prefixed) string functions. Wreszcie, silniki baz danych, takie jak MySQL, obsługują UTF-8 dawno temu.

Jako tymczasowe obejście można wyłączyć ponowne kodowanie istniejących obiektów, ustawiając 4. parametr ($double_encode) funkcji htmlspecialchars() na false.

+0

Dziękujemy! Praca nad dodawaniem fałszywek działała idealnie. Zajrzę do UTF-8. Czytałem na innych forach, że nie jest to konieczne i wymaga dużo pracy, aby go wdrożyć, a czasem nie jest warte czasu. Czy Twoim zdaniem warto przejść na inny? – Clint

+1

@Clint Właściwie nie jest trudno używać UTF-8 (w PHP patrz ['mb_' z prefiksowanymi funkcjami] (http://php.net/manual/en/ref.mbstring.php)). Spróbuj, a ci się spodoba. ;-) –

+0

+1 do Marata za zanotowanie kodowania może być problemem (możesz również uzyskać to samo w bazach danych i uważaj na JSON - kodowanie jest polem minowym). RE: "Czy warto się przestawić"? - Marat powiedział, że ustawienie 4. parametru htmlspecialchars jest "tymczasowym rozwiązaniem" i zgadzam się, że to naprawdę jest wyrzut. Przekopiesz się w głębszą dziurę, chyba że znajdziesz źródło. Tak więc sprawdź zestaw znaków (jak powiedział Marat) lub sprawdź, czy kod koduje - naprawdę warto ustalić i śledzić, które zmienne są zakodowane, a które nie są IMO. – Robbie

3

Nie ma prostej odpowiedzi. Możesz cofnąć się pod kątem &lt;script...&gt; do <script...> i zakończyć w kłopotach, jednak wygląda na to, że kod został podwójnie zakodowany - prawdopodobnie raz na wejściu, a następnie ponownie, gdy wyjdziesz na ekran. Jeśli możesz zagwarantować, że został podwójnie zakodowany, to bezpieczne jest cofnięcie jednego z nich.

Jednak najlepszym rozwiązaniem jest, aby zachować „surową” wartość w pamięci i zdezynfekować/kodowanie do wyprowadzania do baz danych, HTML, JSON itp

Tak - gdy pojawi się wejście, zdezynfekować go do niczego nie chcę, ale nie konwertuj go na HTML, ani nie uciekaj, ani niczego innego na tym etapie. Ucieknij do bazy danych, html zakoduj ją przy wyświetlaniu na ekranie/xml itp.

+0

Tak właśnie się dzieje. Kiedy zbieram wartość wejściową z POST, bardziej niejasne elementy są już automatycznie zakodowane (nie mam zbyt dużego doświadczenia z php i nie wiem dlaczego), jednak wspólne elementy, takie jak &, < and >, są dekodowane. Właśnie dlatego używam podwójnego kodowania. Czy istnieje lepszy sposób na rozwiązanie tego problemu? – Clint

+0

Usuń początkowe kodowanie. Musisz dowiedzieć się, gdzie to się dzieje. – Robbie

+0

Na podstawie innego komentarza uważam, że to przeglądarka automatycznie ucieka z wartości na wejściu. Jak mogę to usunąć? – Clint

Powiązane problemy