2010-08-16 17 views
12

Okazuje się następujących składników, które wygląda jak ważny javascript, nie jest:Jaki jest poprawny sposób kodowania wbudowanego obiektu javascript, aby chronić go przed XSS?

<html> 
<body> 
<script> 
json = {test: "</script><script>alert('hello');</script>"}; 
</script> 
</body> 
</html> 

Ten sam tekst, kiedy wrócił JSON za pośrednictwem ajax api działa tak jak oczekiwano. Jednak po renderowaniu w trybie bezpośrednim powoduje to podstawowe problemy z XSS.

Biorąc pod uwagę arbitralny poprawny ciąg JSON, co muszę zrobić po stronie serwera, aby zapewnić bezpieczne renderowanie w linii?

EDIT Idealnie chciałbym poprawkę do pracy z następującym ciągiem, a także:

json = {test: "<\/script><script>alert('hello');<\/script>"};

znaczenia, nie mam pojęcia, jak mój bazowy biblioteka kodujący / char, może wybrałeś kodowanie lub nie. (Tak jego prawdopodobnie poprawka regex jest bardziej wytrzymałe)

+0

Zasadniczo, jeśli chcesz renderować ją w linii, upewnij się, że nie zawiera ona sekwencji znaków ''. –

+0

lub Chyba ... martwię się wydajnością z prostą korekcją ciągów, a także, że mogą istnieć inne dziwne problemy, których nie jestem świadomy. –

+0

O ile nie dzieje się coś dziwnego, ukryta biblioteka nie wymyka się z ukośnika . Nie ma specjalnego znaczenia w łańcuchu Javacript, więc nie ma powodu, aby z niego uciekać. – Guffa

Odpowiedz

3

Na początek, to nie jest JSON w ogóle, to obiekt JavaScript. JSON to format tekstowy oparty na składni Javascript.

Można też upewnić się, że kod nie zawiera kombinację </ znaków:

var obj = { test: "<"+"/script><script>alert(\"hello\");<"+"/script>" }; 

Lub jeśli używasz XHTML można mieć pewność, że zawartość w tagu skryptu jest interpretowany jako zwykły danych :

<script type="text/javascript"> 
//<![CDATA[ 
var obj = { test: "</script><script>alert(\"hello\");</script>" }; 
//]]> 
</script> 
+0

poprawiono frazowanie w pytaniu, możesz je wprowadzić i poprawić. "" <"+"/"czuje się trochę niepewnie pod względem wydajności, rozwiązanie CDATA jest naprawdę eleganckie –

+0

Właściwie o tym myśląc, poprawka po stronie serwera' gsub ("

+0

@Sam Szafran: Tak, użycie odwrotnego ukośnika działa również w celu zapobiegania kombinacji znaków ' Guffa

2

W dosłownym smyczki, wprowadzić odwrotny ukośnik (\) zanim wszystkie „niebezpieczne” znaków, w tym ukośnik, która występuje w „</script>” (/   →   \/).

To byłoby zmienić na przykład:

json = {test: "<\/script><script>alert(\"hello\");<\/script>"}; 

i to nadal ważne JSON.

Oczywiście trzeba także uciec cudzysłów ("   →   \") i odwrotny ukośnik (\   →   \\), ale to już trzeba zrobić tak. Powinieneś także rozważyć uniknięcie pojedynczego cytatu ('   →   \'), aby był po bezpiecznej stronie.

+0

, więc wystarczy prosta zamiana ("/", "\ /")? jakiekolwiek inne przypadki skrajne? –

+0

@Sam Szafran: Tak, zadbaj o podwójne cudzysłowy, pojedyncze cudzysłowy i ukośniki odwrotne. Zobacz moją zredagowaną odpowiedź. – Timwi

+0

fajne, yerp Już miałem zakodowane, rozszerzając moje pytanie o nieco bardziej owłosioną próbkę. –

1

znalazłem this lista znaków do uciekł ciągów JSON:

\b Backspace (ascii code 08) 
\f Form feed (ascii code 0C) 
\n New line 
\r Carriage return 
\t Tab 
\v Vertical tab 
\' Apostrophe or single quote 
\" Double quote 
\\ Backslash character 

za pomocą PHP? Jeśli tak, to: json_encode

echo json_encode("<\/script><script>alert(\"hello\");<\/script>"); 

wyjściowa:

"<\\\/script><script>alert(\"hello\");<\\\/script>" 

Inny przykład:

echo json_encode("</script><script>alert(\"hello\");</script>"); 

wyjściowa:

"<\/script><script>alert(\"hello\");<\/script>" 
+0

Czy to ucieka przed ukośnikiem? Strona pomocy nie mówi. (Właściwie to nie mówi, co * dowolne * opcji oznacza.) – Timwi

+0

Dodano przykład, wygląda na to, że ucieka przed ukośnikiem :) –

+0

czy możesz rozwinąć algorytm, którego powinienem użyć? Nie używam PHP –

4

Zobacz OWASP's XSS prevention guide (patrz zasada nr 3) -

Wyłączając w przypadku znaków alfanumerycznych, nie zawiera wszystkich znaków mniejszych niż 256 z formatem \ xHH, aby uniemożliwić przejście z wartości danych do kontekstu skryptu lub do innego atrybutu . Nie używaj żadnych uciekających skróty jak \”, ponieważ charakter cytat mogą być dopasowane przez atrybut parser HTML czyli pierwszy

Załóżmy, to w jaki sposób obiekt wygląda -.


var log = { 
trace: function(m1, m2, m3){}, 
debug: function(m1, m2, m3){}, 
currentLogValue : "trace {].a23-%\/^&", 
someOtherObject : {someKey:"somevalue", someOtherKey:"someothervalue"} 
}; 

powinny zakończyć się w ten sposób -


var log = { 
trace : "function\x28m1,\x20m2,\x20m3\x29\x7B\x7D", 
debug : "function\x28m1,\x20m2,\x20m3\x29\x7B\x7D", 
currentLogValue : "trace\x20\x7B\x5D.a23\x2D\x25\x5C\x2F\x5E\x26", 
someOtherObject : {someKey : "somevalue", someOtherKey:"someothervalue"} 
}; 

zasady są proste -

  1. Niezaufany danych jest dopuszczalne tylko w parę cytatów
  2. Cokolwiek jest w cudzysłowie zostanie uciekł następująco - „Z wyjątkiem znaków alfanumerycznych, ucieczka wszystko inne z formatem \ xhh”

To gwarantuje, że niezaufane dane są zawsze interpretowane jako ciąg, a nie jako funkcja/obiekt/cokolwiek innego.

2

Jednym z problemów, na które możesz natknąć się, jest to, że tłumacze HTML i JavaScript wykonują przeplot.

<html> 
<body> 
<script> 
json = {test: "</script><script>alert('hello');</script>"}; 
</script> 
</body> 
</html> 

W przykładzie interpreter HTML da json = {test: " do tłumacza js a potem znajdzie następny blok Javascript (rozdzielany przez <script> i </script> tagów) i dać alert('hello'); do interpretera JS. Nie ma znaczenia, że ​​znacznik </script> jest w łańcuchu javascript, ponieważ interpreter HTML jest tym, który szuka bloków kodu js i nie rozumie ciągów js.

Pierwsza sekcja spowoduje błąd składni js, podczas gdy druga sekcja wygeneruje alert. Rozumiem, że to nie odpowiada na twoje pytanie, co robić, ale może rzuci to więcej światła na to, co dzieje się pod maską.

Powiązane problemy