2010-09-10 42 views
11

Tôi đang cố gắng để khử trùng và XSS-proof một số đầu vào HTML từ máy khách. Tôi đang sử dụng Python 2.6 với Beautiful Soup. Tôi phân tích đầu vào, loại bỏ tất cả các thẻ và thuộc tính không có trong danh sách trắng và chuyển đổi cây thành chuỗi.Làm thế nào để tạo ra các thực thể HTML đầu ra của Beautiful Soup?

Tuy nhiên ...

>>> unicode(BeautifulSoup('text < text')) 
u'text < text' 

Đó không giống như HTML hợp lệ đối với tôi. Và với thẻ stripper của tôi, nó sẽ mở đường cho tất cả các loại nastiness:

>>> print BeautifulSoup('<<script></script>script>alert("xss")<<script></script>script>').prettify() 
< 
<script> 
</script> 
script>alert("xss")< 
<script> 
</script> 
script> 

Các cặp <script></script> sẽ bị xóa, và những gì còn lại là không chỉ là một cuộc tấn công XSS, nhưng ngay cả HTML hợp lệ là tốt.

Giải pháp hiển nhiên là thay thế tất cả < ký tự theo &lt;, sau khi phân tích cú pháp, không được thuộc về thẻ (và tương tự cho >&'"). Nhưng Beautiful Soup documentation chỉ đề cập đến việc phân tích cú pháp của các thực thể, chứ không đề cập đến việc tạo ra chúng. Tất nhiên tôi có thể chạy một thay thế trên tất cả các nút NavigableString, nhưng kể từ khi tôi có thể bỏ lỡ một cái gì đó, tôi muốn cho một số mã thử và thử nghiệm làm công việc.

Tại sao Soup đẹp không thoát < (và các ký tự ma thuật khác) theo mặc định và làm cách nào để tôi làm điều đó?


N.B. Tôi cũng đã xem lxml.html.clean. Nó dường như làm việc trên cơ sở danh sách đen, không phải danh sách trắng, vì vậy nó không có vẻ rất an toàn với tôi. Thẻ có thể được đưa vào danh sách trắng, nhưng thuộc tính không thể và cho phép quá nhiều thuộc tính cho sở thích của tôi (ví dụ: tabindex). Ngoài ra, nó cung cấp một số AssertionError trên đầu vào <SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>. Không tốt.

Đề xuất cho các cách khác để làm sạch HTML cũng rất được hoan nghênh. Tôi hầu như không phải là người duy nhất trên thế giới cố gắng làm điều này, nhưng dường như không có giải pháp tiêu chuẩn nào cả.

+0

'văn bản Gumbo

+0

Ồ, đúng vậy. Dù sao, nó cũng giống với 'text 'mà tôi đã trình bày. – Thomas

Trả lời

2

Lớp lxml.html.clean.Cleaner cho phép bạn cung cấp danh sách trắng thẻ với đối số allow_tags và sử dụng danh sách trắng thuộc tính được xác định trước từ feedparser với đối số safe_attrs_only. Và lxml chắc chắn xử lý các thực thể đúng cách trên serialization.

+0

Giống như tôi đã viết trong câu hỏi ban đầu, nó không cho phép tôi thay đổi danh sách các thuộc tính. Ví dụ, 'tabindex' có thể làm cho trang web hoạt động theo cách bất ngờ, và với trí tưởng tượng, các thuộc tính mã hóa khác nhau như' charset' có thể được sử dụng cho mục đích độc hại, trong khi chúng hiếm khi (nếu có) hữu ích. Tôi chỉ muốn cho phép các thuộc tính thực sự hữu ích (và được sử dụng). – Thomas

+0

Chúng nằm trong danh sách các thuộc tính được feedparser chấp nhận, điều này khá hoang tưởng. Nếu bạn hoang tưởng hơn, bạn có thể đặt 'lxml.html.defs.safe_attrs' thành chỉ các thuộc tính mà bạn xem là an toàn. Ngoài ra, nếu không hoàn toàn nằm ngoài giá, bạn có thể sử dụng lại lớp 'feedparser._HTMLSanitizer', sửa đổi nó cho phù hợp với các thuộc tính bạn muốn cho phép. – llasram

+2

Tôi không thích danh sách đó. Phần tử '

' nằm trên đó.Oh, và tôi chỉ phát hiện lỗi đánh máy trong 'lxml/html/defs.py':' marque' thay vì 'marquee', vẫn xuất hiện trong phiên bản svn. Tôi đã báo cáo một lỗi. Không phải là một vấn đề lớn, nhưng nó không giúp xây dựng lòng tin ... – Thomas

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