2010-08-16 24 views
12

Hóa ra sau trông giống như javascript hợp lệ, không phải là:Cách chính xác để mã hóa một đối tượng javascript nội tuyến là gì, để bảo vệ nó khỏi XSS?

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

Các văn bản tương tự, khi trở về JSON qua một api ajax công trình cũng giống như mong đợi. Tuy nhiên khi kết quả in-line trong một vấn đề XSS cơ bản.

Cho chuỗi JSON chính xác tùy ý, tôi cần làm gì với phía máy chủ để đảm bảo an toàn cho hiển thị trong dòng?

EDIT Lý tưởng nhất là tôi muốn sửa chữa để làm việc với các chuỗi sau đây cũng như:

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

Ý nghĩa, tôi không có ý tưởng như thế nào thư viện cơ bản của tôi là mã hóa các / char, nó có thể đã chọn mã hóa hoặc có thể không. (Vì vậy nó có thể là một sửa chữa regex là mạnh mẽ hơn)

+0

Về cơ bản, nếu bạn muốn hiển thị trực tuyến, bạn cần đảm bảo nó không chứa chuỗi ký tự ' '. –

+0

hoặc Tôi đoán ... Tôi lo lắng về hiệu suất với một sửa chuỗi nối đơn giản và cũng có thể có các vấn đề lạ khác mà tôi không biết về –

+0

Trừ khi có điều gì đó kỳ lạ xảy ra, thư viện cơ bản không thoát khỏi ký tự gạch chéo . Nó không có ý nghĩa đặc biệt trong một chuỗi Javacript, vì vậy không có lý do gì để thoát khỏi nó. – Guffa

Trả lời

3

Để bắt đầu, đây không phải là JSON ở tất cả, nó là một đối tượng Javascript. JSON là một định dạng văn bản dựa trên cú pháp Javascript.

Bạn có thể chắc chắn rằng mã không chứa sự kết hợp </ nhân vật:

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

Hoặc nếu bạn đang sử dụng XHTML bạn có thể chắc chắn rằng nội dung trong thẻ script được hiểu như là dữ liệu đơn giản :

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

đã sửa chữa các câu trả lời trong câu hỏi, cảm thấy tự do để bước vào và tiếp tục sửa nó. Các "" <"+"/"cảm thấy một chút hiệu suất iffy khôn ngoan, giải pháp CDATA thực sự là thanh lịch –

+0

Thực sự suy nghĩ về nó, một sửa chữa phía máy chủ của' gsub ("

+0

@Sam Saffron: Có, sử dụng dấu gạch chéo ngược cũng hoạt động để ngăn chặn tổ hợp ký tự ' Guffa

2

Trong chuỗi chữ, đặt một dấu chéo ngược (\) trước khi tất cả các nhân vật “không an toàn”, bao gồm các dấu gạch chéo xảy ra trong “</script>” (/   →   \/).

Điều này sẽ thay đổi ví dụ của bạn để:

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

và nó vẫn sẽ là JSON hợp lệ.

Tất nhiên bạn cũng phải thoát khỏi đôi quote ("   →   \") và dấu chéo ngược bản thân (\   →   \\), nhưng bạn sẽ đã có để làm điều đó anyway. Bạn cũng nên xem xét thoát khỏi dấu nháy đơn ('   →   \') để an toàn.

+0

để thay thế đơn giản ("/", "\ /") nên làm gì? bất kỳ trường hợp cạnh khác? –

+0

@Sam Saffron: Có, chăm sóc các dấu ngoặc kép, dấu nháy đơn và dấu gạch chéo ngược. Xem câu trả lời đã chỉnh sửa của tôi. – Timwi

+0

tuyệt vời, yerp Tôi đã có những mã được mã hóa, mở rộng câu hỏi của tôi với một mẫu hơi to hơn một chút. –

1

tôi thấy this danh sách các nhân vật để được thoát cho chuỗi 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 

Sử dụng PHP? Nếu vậy: json_encode

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

Output:

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

Một ví dụ khác:

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

Output:

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

Điều đó có thoát khỏi dấu gạch chéo không? Trang trợ giúp không nói. (Trong thực tế, nó không nói những gì * bất kỳ * của các tùy chọn có nghĩa là.) – Timwi

+0

Thêm ví dụ, có vẻ như nó thoát khỏi dấu gạch chéo phía trước :) –

+0

bạn có thể mở rộng trên thuật toán tôi nên sử dụng? Tôi không sử dụng PHP –

4

Xem OWASP's XSS prevention guide (Xem Quy tắc 3 #) -

Trừ đối với các ký tự chữ và số, hãy xóa tất cả ký tự ít hơn 256 với định dạng \ xHH để ngăn không cho chuyển giá trị dữ liệu thành ngữ cảnh tập lệnh hoặc thành thuộc tính khác. Không sử dụng bất kỳ thoát các phím tắt như \" vì nhân vật quote có thể được xuất hiện bằng cách phân tích cú pháp thuộc tính HTML chạy đầu tiên

Giả sử đây là cách đối tượng của bạn trông giống như -.


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

Điều này sẽ kết thúc như thế này -


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"} 
}; 

Quy tắc rất đơn giản -

  1. dữ liệu không tin cậy chỉ được phép trong một cặp dấu ngoặc kép
  2. Dù nằm trong dấu ngoặc kép được thoát như sau - "Ngoại trừ ký tự chữ và số, thoát khỏi mọi thứ khác với định dạng \ xHH"

này đảm bảo rằng dữ liệu không tin cậy luôn được hiểu là một chuỗi và không phải là một hàm/đối tượng/bất kỳ thứ gì khác.

2

Một vấn đề bạn có thể gặp phải là thực tế là trình thông dịch HTML và javascript trên trình duyệt chạy xen kẽ.

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

Trong ví dụ của bạn, người phiên dịch HTML sẽ cung cấp cho json = {test: " để người phiên dịch js và sau đó nó sẽ tìm ra khối javascript tiếp theo (giới hạn bởi <script></script> tags) và cung cấp cho alert('hello'); để người phiên dịch js. Không quan trọng là thẻ </script> nằm trong chuỗi javascript, bởi vì trình thông dịch HTML là thẻ tìm mã khối js và không hiểu chuỗi js.

Phần đầu tiên sẽ gây ra lỗi cú pháp js, trong khi phần thứ hai sẽ tạo cảnh báo. Tôi nhận ra điều này không trả lời câu hỏi của bạn về việc phải làm gì, nhưng có lẽ nó sẽ làm sáng tỏ những gì đang xảy ra dưới mui xe.

Các vấn đề liên quan