แนวทางปฏิบัติที่ดีที่สุด: การล้าง HTML ที่ผู้ใช้สร้างขึ้น

ฉันกำลังเขียนโค้ดตัวแก้ไขความกว้างแบบ WYSIWYG designMode="on" บน iframe ตัวแก้ไขทำงานได้ดีและฉันเก็บโค้ดตามที่อยู่ในฐานข้อมูล

ก่อนที่จะส่งออก html ฉันจำเป็นต้อง "ล้าง" ด้วย php บนฝั่งเซิร์ฟเวอร์เพื่อหลีกเลี่ยงการเขียนสคริปต์ข้ามไซต์และสิ่งที่น่ากลัวอื่น ๆ มีวิธีปฏิบัติที่ดีที่สุดในการทำเช่นนี้หรือไม่? แท็กใดที่อาจเป็นอันตรายได้?

อัปเดต: แก้ไขการพิมพ์ผิด มันเป็นสิ่งที่คุณเห็นคือสิ่งที่คุณได้รับ ไม่มีอะไรใหม่ :)


person Martin    schedule 05.05.2010    source แหล่งที่มา
comment
หากคุณมุ่งมั่นที่จะนำสิ่งนี้ไปใช้ด้วยตนเอง คุณควรดูที่ ha.ckers.org/ xss.html - รายการการโจมตีที่รู้จักในเบราว์เซอร์ต่างๆ   -  person FalseVinylShrub    schedule 06.05.2010
comment
คำถามที่ดี - ฉันสงสัยว่า stackoverflow ป้องกันตัวเองได้อย่างไร ...   -  person JDelage    schedule 25.03.2011


คำตอบ (4)


แนวทางปฏิบัติที่ดีที่สุดคืออนุญาตให้เฉพาะบางสิ่งที่คุณรู้ว่าไม่เป็นอันตราย และกำจัด/หลบหนีส่วนที่เหลือทั้งหมด ดูรายงาน ที่เป็นอันตรายโดยอัตโนมัติ การตรวจจับและกำจัดโค้ดบนเว็บ (OWASP AntiSamy) สำหรับการสนทนาเกี่ยวกับเรื่องนี้ (ไลบรารีมีไว้สำหรับ Java แต่หลักการจะนำไปใช้กับภาษาใดก็ได้)

person Chris Lercher    schedule 05.05.2010
comment
ฉันเริ่มต้นแบบนั้น แต่เนื่องจากเบราว์เซอร์ทั้งหมดใช้สิ่งนี้แตกต่างกัน ฉันจึงได้รับแท็กจำนวนมากสำหรับสิ่งเดียวกับที่ฉันต้องอนุญาต ตัวอย่างเช่น ข้อความตัวหนาทำได้อย่างน้อย 3 วิธี ดังนั้นมันจะเป็นชุด regex ชุดใหญ่ คุณยังสามารถวาง html ที่จัดรูปแบบแล้วตามที่คุณต้องการในโปรแกรมแก้ไขได้ เช่น จากอีเมล html หรืออะไรก็ได้ และนั่นดูดีในตัวแก้ไข แต่จะไม่ทำงานหลังจากการหลบหนี - person Martin; 05.05.2010
comment
นั่นเป็นสาเหตุที่ AntiSamy มาพร้อมกับชุดตัวอย่างบางส่วนแล้ว อาจเป็นไปได้ว่ายังมีไลบรารี PHP (หรือคุณสามารถสร้างมันขึ้นมาได้) คุณจะ ไม่มีวัน บรรลุผลสำเร็จ (โดยการขึ้นบัญชีดำ): ทุกคนที่ลองสิ่งนี้มาก่อนล้วนล้มเหลว - มันเป็นไปไม่ได้ตามความเป็นจริง - จะ มีบางสิ่งที่คุณไม่ได้กล่าวถึง (ซึ่งเป็นอันตรายถึงชีวิตสำหรับการขึ้นบัญชีดำ แต่ไม่สำคัญมากนักเมื่ออยู่ในบัญชีขาว) ตามหลักการแล้ว หากคุณสามารถหลีกเลี่ยง HTML ได้ ให้ใช้ Markdown ฯลฯ ตามที่ Hank แนะนำ! - person Chris Lercher; 05.05.2010
comment
@Martin คุณ จริงๆ ไม่ควรใช้ regexes สำหรับสิ่งนี้ มีเหตุผล คำตอบนี้ได้รับ (สุทธิ) 3,000 โหวต - person Hank Gay; 05.05.2010
comment
โอเค ตอนนี้ฉันมั่นใจแล้วว่าฉันควรทำไวท์ลิสต์แทนแบล็คลิสต์ @Hank Gay: แต่ฉันจะไม่แยกวิเคราะห์ html จริงๆ ฉันแค่จะแทนที่ ‹ ด้วย แล้วแทนที่กลับเป็น ‹ ในรูปแบบที่รู้จักชุดเล็ก ๆ ยังเหมือนไปเดทกับซาตานอยู่มั้ย? - person Martin; 06.05.2010

หากคุณตั้งใจจะยอมทำเช่นนั้นจริงๆ คุณควรใช้วิธีการไวท์ลิสต์

แนวทางที่ดีที่สุดน่าจะเป็นการไม่อนุญาต HTML และใช้รูปแบบมาร์กอัปแบบง่ายแทน คุณสามารถเรนเดอร์เป็น HTML ล่วงหน้าและเก็บไว้ในฐานข้อมูลได้หากประสิทธิภาพเป็นปัญหา การหลีกเลี่ยงปัญหาประเภทนี้คือหนึ่งในเหตุผลสำคัญในการใช้ Markdown, สิ่งทอ, ข้อความที่มีโครงสร้างใหม่ ฯลฯ

หมายเหตุ: ฉันเชื่อมโยงกับ GitHub-Flavored Markdown (GFM) ไม่ใช่ Standard Markdown (SM) GFM จัดการกับปัญหาทั่วไปบางประการที่ผู้ใช้ปลายทางมีกับ SM

person Hank Gay    schedule 05.05.2010

ฉันดูคำถามเดียวกันเมื่อเร็ว ๆ นี้โดยใช้ Perl เป็นภาษาฝั่งเซิร์ฟเวอร์

ขณะทำเช่นนั้น ฉันบังเอิญเจอ HTML Purifier ซึ่งอาจเป็นสิ่งที่คุณต้องการ แต่เห็นได้ชัดว่าเป็นภาษา PHP ไม่ใช่ Perl ฉันจึงไม่ได้ทดสอบมันจริงๆ

นอกจากนี้ ในการวิจัยของฉัน ฉันได้ข้อสรุปว่านี่เป็นธุรกิจที่ยุ่งยากมากและพิจารณาว่าเป็นไปได้หรือไม่โดยใช้ภาษามาร์กอัปที่เรียบง่าย เช่น Markdown ตามที่ Hank Gay แนะนำ

person FalseVinylShrub    schedule 05.05.2010

หากคุณคุ้นเคยกับ ASP .NET เพียงดำเนินการ Server.htmlencode() เพื่อแปลงอักขระพิเศษ เช่น ‹ > เป็น "& g t;" "&ล ;"

ใน php คุณสามารถใช้ฟังก์ชัน htmlspecialchars() ได้

เมื่อเข้ารหัสอักขระพิเศษแล้ว จะสามารถป้องกันการเขียนสคริปต์ข้ามไซต์ได้

person TechTravelThink    schedule 05.05.2010
comment
แต่นั่นเป็นการปิดการใช้งาน html ฉันต้องการที่จะอนุญาต html แต่ลบแท็กที่เป็นอันตรายเช่น iframe และสคริปต์ - person Martin; 05.05.2010
comment
จากนั้นใช้มาร์กอัปที่ออกแบบมาโดยเฉพาะสำหรับข้อความ เช่น bbcode หรือ wikicode และโปรแกรมแก้ไขที่เหมาะสม - person symcbean; 05.05.2010