2009-04-23 37 views
17

Đôi khi, phía máy chủ sẽ tạo chuỗi được nhúng trong mã JavaScript nội tuyến. Ví dụ, nếu "UserName" nên được tạo ra bởi ASP.NET. Sau đó, nó trông giống như.Có cần phải "thoát" ký tự "<" and ">" cho chuỗi javascript không?

<script> 
    var username = "<%UserName%>"; 
</script> 

Đây không phải là an toàn, bởi vì người dùng có thể có/tên của mình là

</script><script>alert('bug')</script></script>

Đó là XSS lỗ hổng.

Vì vậy, về cơ bản, mã nên được:

<script> 
    var username = "<% JavascriptEncode(UserName)%>"; 
</script> 

JavascriptEncode làm là thêm charater "\" trước khi "/" và "'" và "" "Vì vậy, html đầu ra. cũng giống như var username = "</script> alert (\ 'lỗi \') </script> </script>";.

Trình duyệt sẽ không giải thích "</script> "dưới dạng kết thúc khối tập lệnh. Vì vậy, XSS trong tránh.

Tuy nhiên, vẫn còn "<" và ">" ở đó. Nó được đề nghị để thoát khỏi hai nhân vật là tốt. Trước hết, tôi không tin rằng nên thay đổi "<" thành "& lt;" và ">" đến "& gt;" đây. Và, tôi không chắc chắn thay đổi "<" thành "\ <" và ">" thành "\>" có thể nhận biết được đối với tất cả các trình duyệt. Có vẻ như không cần phải mã hóa thêm cho "<" và ">".

Có đề xuất nào về điều này không?

Cảm ơn.

Trả lời

16

Sự cố có các câu trả lời khác nhau tùy thuộc vào ngôn ngữ đánh dấu bạn đang sử dụng.

Nếu bạn đang sử dụng HTML, thì bạn không được đại diện cho họ với các thực thể dưới dạng phần tử tập lệnh được đánh dấu là có chứa CDATA.

Nếu bạn đang sử dụng XHTML, thì bạn có thể trình bày chúng dưới dạng CDATA với các dấu hiệu CDATA rõ ràng hoặc bạn có thể trình bày chúng với các thực thể.

Nếu bạn đang sử dụng XHTML, nhưng phân phối nó dưới dạng văn bản/html, thì bạn cần viết một cái gì đó tuân theo các quy tắc của XHTML nhưng vẫn hoạt động với trình phân tích cú pháp văn bản/html. Điều này thường có nghĩa là sử dụng các đánh dấu CDATA rõ ràng và nhận xét chúng trong JavaScript.

<script type="text/javascript"> 
// <![CDATA[ 
    … 
// ]]> 
</script> 

Cách đây không lâu, tôi đã viết một chút về the hows and whys of this.

+1

Nhưng vẫn còn '>' trong ']]>' bên trong khối CDATA phải được thay thế bằng '>'. Vì vậy, 'foo [bar [0]]> 1234' phải được thay thế bằng' foo [bar [0]] < 1234' hoặc 'foo [bar [0]]> 1234'. Nếu không, khối CDATA sẽ bị đóng sớm. – Gumbo

+0

Vì CDATA hiển thị ký tự là "&" chứ không phải "Bắt đầu thực thể" - điều đó sẽ không hoạt động. Nếu bạn cần đại diện cho chuỗi "]]>" bên trong CDATA thì tôi chắc chắn bạn đang hút và nên sử dụng các thực thể để bắt đầu (bên ngoài khối CDATA) – Quentin

+7

Hoặc chỉ cần thêm một dấu cách: 'foo [bar [0 ]]> 1234' - hoặc nếu là một phần của chuỗi: ''foo [bar [0]]' + '> 1234'' - hoặc chỉ chứa tất cả tập lệnh của bạn trong tệp .js bên ngoài. – gnarf

13

Không, bạn không được thoát <> bằng các thực thể HTML bên trong <script> trong HTML.

  • Sử dụng JavaScript chuỗi thoát quy tắc (thay thế \ với \\" với \")
  • thay thế tất cả các lần xuất hiện của </ với <\/, để ngăn chặn thoát ra khỏi các yếu tố <script>.

Trong XHTML phức tạp hơn.

  • Nếu bạn gửi XHTML dưới dạng XML (cách không tương thích với IE) và không sử dụng khối CDATA, thì bạn cần phải thoát khỏi thực thể, ngoài thoát chuỗi JavaScript.
  • Nếu bạn gửi XHTML dưới dạng XML và sử dụng khối CDATA, thì không được thoát khỏi thực thể, nhưng thay thế ]]> bằng ]]]]><![CDATA[> để tránh thoát ra khỏi nó (ngoài việc thoát chuỗi JavaScript).
  • Nếu bạn gửi XHTML là text/html (99% số người làm) thì bạn phải sử dụng khối CDATA XML, thoát XML CDATA và HTML thoát tất cả cùng một lúc.
+5

+1. Nitpick nhỏ: không _all_ lần xuất hiện của ' ', hoặc'/'sẽ kết thúc thẻ mở tương ứng.] (Http://mths.be/etago) –

2

Cách rẻ và dễ dàng:

<script type="text/javascript"> 
    var username = "<%= Encode(UserName) %>"; 
</script> 

nơi chương trình mã hóa trong Encode là dịch mỗi ký tự của đầu vào cho liên \xABCD đại diện tương thích với JavaScript.

Một cách rẻ tiền và dễ dàng:

<script type="text/javascript"> 
    var username = decodeBase64("<%= EncodeBase64(UserName) %>"); 
</script> 

nếu bạn đang đối phó với chỉ ASCII.

Tất nhiên, pst đánh vào đầu bằng cách thực hiện nghiêm ngặt.

+0

+1 Ngoài ra, giải pháp này làm cho mã nguồn đầu ra của bạn trông h4x0r! –

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