เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ · URL ตัวเข้ารหัสและตัวถอดรหัส
การเข้ารหัส URL ไม่ใช่การฆ่าเชื้อ: พารามิเตอร์ที่ถอดรหัสแล้วยังคงต้องมีการ Escape
· เหตุใดจึงสำคัญ
การเข้ารหัส URL ความปลอดภัย xss
การเข้ารหัสเปอร์เซ็นต์ปกป้องโครงสร้าง URL ไม่ใช่ HTML, SQL หรือเชลล์ของคุณ โพสต์นี้อธิบายว่าทำไมค่าที่เข้ารหัสอย่างถูกต้องจึงเป็นอันตรายอีกครั้งทันทีที่ถอดรหัส และค่า Escape ค่าใดเป็นของที่ใด
เหตุใดการเข้ารหัส URL เพียงอย่างเดียวจึงไม่สามารถหยุดการโจมตี XSS ได้
พารามิเตอร์ "ปลอดภัย" สามารถเรียกใช้สคริปต์ได้หากเข้ารหัสสำหรับการส่ง แต่ถอดรหัสก่อนเรนเดอร์ พิจารณา XSS เพย์โหลด เช่น แท็ก img พร้อมด้วยตัวจัดการ onerror ที่เข้ารหัสเปอร์เซ็นต์เป็น %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E หากสิ่งนี้เดินทางใน URL และถอดรหัสด้วยรหัสแอปพลิเคชันก่อนที่จะแทรกลงใน HTML เบราว์เซอร์จะเห็นมาร์กอัปดั้งเดิมและดำเนินการตัวจัดการ การเข้ารหัสเปอร์เซ็นต์เป็นเลเยอร์การแสดง ไม่เปลี่ยนภัยคุกคามที่ซ่อนอยู่
เพย์โหลดจะปลอดภัยเฉพาะในระหว่างการส่งข้อมูล เมื่อเป็นสตริงที่เข้ารหัสโดยไม่มีความหมายพิเศษกับ HTTP หรือ URL parser ทันทีที่ถอดรหัส มันก็กลายเป็นอันตรายอีกครั้งเพราะกลับคืนสู่รูปแบบดั้งเดิม บริบทดาวน์สตรีมทุกรายการต้องใช้กฎการ Escape ของตัวเองให้เหมาะสมกับวิธีการใช้ข้อมูล การเข้ารหัส URL ไม่สามารถทดแทนการหลบหนี HTML, การกำหนดพารามิเตอร์ SQL หรือการจัดการอาร์กิวเมนต์ของเชลล์
การเข้ารหัสเปอร์เซ็นต์มีไว้เพื่ออะไร — ทำให้ตัวคั่นไม่คลุมเครือบนเส้นลวด ไม่มีอะไรเพิ่มเติม
การเข้ารหัสเปอร์เซ็นต์สามารถปกป้องโครงสร้าง URL ได้อย่างแม่นยำ เครื่องหมายและยังคงเป็นส่วนหนึ่งของไวยากรณ์สตริงข้อความค้นหา ไม่ได้รับการตีความใหม่ว่าเป็นตัวคั่น เครื่องหมายทับไม่กลายเป็นตัวแยกเส้นทาง เครื่องหมายคำถามไม่เริ่มต้นส่วน ด้วยการเข้ารหัสอักขระที่สงวนไว้เป็น %XX โปรแกรมแยกวิเคราะห์จะถือว่าอักขระเหล่านี้เป็นข้อมูล ไม่ใช่ไวยากรณ์ วิธีนี้ใช้ได้กับงานเดียว: ทำให้ URL โครงสร้างไม่คลุมเครือบนเส้นลวด
การถอดรหัสจะทำให้ถนนเดินรถทางเดียวกลับตรงกันข้าม ไบต์ที่กู้คืนคือสิ่งที่ถูกเข้ารหัสอย่างแน่นอน ไม่มีอะไรมากหรือน้อยไปกว่านั้น HTML-สตริงอันตรายยังคงเป็นอันตราย SQL-เวกเตอร์การฉีดยังคงเป็นอันตราย และคำสั่งเชลล์ยังคงเป็นอันตราย การเข้ารหัสเปอร์เซ็นต์ไม่ใช่การตรวจสอบอินพุต ไม่ใช่การฆ่าเชื้อ และไม่ใช่ขอบเขตด้านความปลอดภัย เป็นรูปแบบการนำเสนอเท่านั้น
การถอดรหัสจะกู้คืนไบต์ดั้งเดิม ดังนั้นทุกบริบทดาวน์สตรีมจึงเห็นค่าดิบอีกครั้ง
การหลบหนีเฉพาะบริบทคือจุดที่การปกป้องที่แท้จริงเกิดขึ้นอย่างแท้จริง HTML บริบทต้องการเอนทิตี: น้อยกว่ากลายเป็น <, มากกว่ากลายเป็น >, เครื่องหมายคำพูดกลายเป็น ", เครื่องหมายและกลายเป็น & SQL บริบทต้องการคิวรีที่กำหนดพารามิเตอร์เพื่อแยกโครงสร้างออกจากข้อมูล ป้องกันไม่ให้ผู้โจมตีแยกออก บริบทของเชลล์ต้องการอาร์เรย์อาร์กิวเมนต์เพื่อหลีกเลี่ยงการแยกคำและการรวมกลุ่มอย่างสมบูรณ์
แต่ละบริบทมีอักขระที่เป็นอันตรายแตกต่างกันและมีกฎการหลบหนีที่แตกต่างกันอย่างชัดเจน เอนทิตี HTML ไม่เป็นอันตรายในแบบสอบถาม SQL แต่ไม่มีประโยชน์สำหรับการป้องกันที่นั่น แบ็กสแลชป้องกันการแทรก SQL ในบางฐานข้อมูล แต่ไม่ใช่ฐานข้อมูลอื่น การ Escape ของเชลล์ขึ้นอยู่กับสไตล์การอ้างอิง นักพัฒนาจะต้องเข้าใจปลายทางก่อนที่จะเลือกวิธีจัดการข้อมูล
การหลบหนีเฉพาะบริบท - HTML เอนทิตีสำหรับมาร์กอัป, คิวรีแบบกำหนดพารามิเตอร์สำหรับ SQL, อาร์เรย์อาร์กิวเมนต์สำหรับเชลล์
ตัวอย่างการทำงาน: การติดตามเพย์โหลดจากลิงก์ไปยังล็อกไปยังเพจเผยให้เห็นว่าการเข้ารหัสและการ Escape จะต้องเกิดขึ้นที่ใด ลิงก์มีเพย์โหลด XSS ที่เข้ารหัสเป็นพารามิเตอร์การค้นหา เซิร์ฟเวอร์ได้รับมันยังคงเข้ารหัสในเนื้อหาคำขอ HTTP แอปพลิเคชันถอดรหัสพารามิเตอร์แบบสอบถามเพื่อแสดงในหน้า หากไม่มีการหลบหนีเอาต์พุต เบราว์เซอร์จะเรนเดอร์เพย์โหลดเป็น HTML และดำเนินการ
หากมีการบันทึกพารามิเตอร์เดียวกันลงในไฟล์ รายการบันทึกจะมีเพย์โหลดที่ถอดรหัสไว้อย่างชัดเจน แอปพลิเคชันที่สองอ่านบันทึก ถอดรหัสอีกครั้ง แทรกลงในหน้า HTML โดยไม่หลบหนี เพย์โหลดดำเนินการครั้งที่สอง ในแต่ละขั้นตอน บริบทจะกำหนดว่าอะไรปลอดภัย การถอดรหัส URL ปลอดภัย การจัดเก็บไฟล์มีความปลอดภัย แต่เอาต์พุต HTML ที่ไม่มีการหลบหนีนั้นเป็นอันตรายถึงชีวิต
ตัวอย่างการทำงาน: การติดตามเพย์โหลดเดียวจากลิงก์ไปยังล็อกไปยังเพจ — ตำแหน่งที่ถูกเข้ารหัส, ตำแหน่งที่ถูกถอดรหัส, ตำแหน่งที่ต้องหลบหนี
การเข้ารหัสเป็นเครื่องมือหลบเลี่ยงตัวกรองแสดงให้เห็นว่าเหตุใดผู้โจมตีจึงเข้ารหัสสองครั้งและผสมตัวพิมพ์ฐานสิบหกอย่างมีนัยสำคัญ หากไฟร์วอลล์ค้นหาแท็ก img ผู้โจมตีจะส่ง %3Cimg และหวังว่าแอปพลิเคชันจะถอดรหัสหนึ่งครั้ง แต่ไฟร์วอลล์ไม่ถอดรหัส หากการตรวจสอบความถูกต้องปฏิเสธ %3Cimg แต่อนุญาตให้ใช้ตัวพิมพ์ที่แตกต่างกัน ไบต์เดียวกันจะถอดรหัสเป็นเพย์โหลดเดียวกัน ความปลอดภัยขึ้นอยู่กับรูปแบบที่เข้ากันกับอินพุตที่เข้ารหัสจะเปราะ
การถอดรหัสจะต้องแม่นยำและคาดเดาได้อย่างแน่นอน รูปแบบ Canonical (เลขฐานสิบหกตัวพิมพ์เล็ก การเข้ารหัสที่รู้จัก) ช่วยให้ใช้นโยบายที่สอดคล้องกัน แต่ไม่สามารถแก้ปัญหาพื้นฐานได้ วิธีการที่เชื่อถือได้เท่านั้นคืออนุญาตให้ถอดรหัสได้เมื่อจำเป็น และใช้การ Escape เอาต์พุตเฉพาะบริบททันทีก่อนใช้งาน การถอดรหัสไม่เคยปลอดภัย จำเป็นสำหรับการส่งสัญญาณเท่านั้น
การเข้ารหัสเป็นเครื่องมือหลบเลี่ยงตัวกรอง — เหตุใดผู้โจมตีจึงเข้ารหัสสองครั้งและผสมเลขฐานสิบหก และเหตุใดการถอดรหัสจึงต้องแม่นยำ
การป้องกัน XSS เต็มรูปแบบจำเป็นต้องมีความเข้าใจการไหลของข้อมูลอย่างสมบูรณ์ บริบทที่ส่งผ่านในแต่ละขั้นตอน สิ่งที่การหลีกเลี่ยงแต่ละบริบทต้องการ การเข้ารหัส URL เป็นเพียงส่วนเล็กๆ: จะคงโครงสร้างไว้ระหว่างการส่งเท่านั้น แต่ชิ้นเดียวก็ป้องกันไม่ได้ด้วยตัวเองเลยทีเดียว นักพัฒนาหลายรายรวมการเข้ารหัสเข้ากับการฆ่าเชื้อ เนื่องจากทั้งสองอย่างนี้เกี่ยวข้องกับการเปลี่ยนอักขระ แต่ทำหน้าที่สำคัญที่แตกต่างกันโดยสิ้นเชิง
ไฟร์วอลล์แอปพลิเคชันเว็บสามารถตรวจจับรูปแบบในเพย์โหลดคำขอได้ แต่การเข้ารหัสจะหลบเลี่ยงเทคนิคการจับคู่รูปแบบง่ายๆ ได้อย่างง่ายดาย การปรับแต่ง WAF นั้นซับซ้อนและเกินกว่าการเข้ารหัส URL การป้องกันที่เชื่อถือได้คือการหลบหนีเอาต์พุตในโค้ดของแอปพลิเคชัน ควบคู่ไปกับการตรวจสอบอินพุตซึ่งเหมาะสมกับบริบทและข้อกำหนดเฉพาะของคุณ
สิ่งนี้ไม่ครอบคลุมถึง - คู่มือการป้องกัน XSS ฉบับเต็มหรือการปรับแต่งไฟร์วอลล์เว็บแอปพลิเคชัน
การป้องกัน XSS เต็มรูปแบบจำเป็นต้องมีความเข้าใจการไหลของข้อมูลอย่างสมบูรณ์ บริบทที่ส่งผ่านในแต่ละขั้นตอน สิ่งที่หลีกเลี่ยงความต้องการบริบทแต่ละอย่างตลอดทั้งแอปพลิเคชัน การเข้ารหัส URL เป็นเพียงส่วนเล็กๆ: จะคงโครงสร้างไว้ระหว่างการส่งเท่านั้น แต่ชิ้นเดียวก็ป้องกันไม่ได้ด้วยตัวเองเลยทีเดียว นักพัฒนาหลายรายรวมการเข้ารหัสเข้ากับการฆ่าเชื้อ เนื่องจากทั้งสองอย่างนี้เกี่ยวข้องกับการเปลี่ยนอักขระ แต่ทำหน้าที่สำคัญที่แตกต่างกันโดยสิ้นเชิงตลอดการพัฒนา
ทดสอบเพย์โหลดตั้งแต่ต้นทางถึงปลายทางเพื่อดูว่าการเข้ารหัสและการ Escape มีความสำคัญอย่างแท้จริงตลอดกระบวนการทั้งหมดตรงไหน วาง %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E ลงในตัวถอดรหัส URL และนาฬิกาจะกลายเป็นสตริงที่ดูเหมือนมาร์กอัป จากนั้นวางผลลัพธ์ลงใน HTML เอนทิตี Escaper เพื่อดูว่ากลายเป็นข้อความที่ปลอดภัยได้อย่างไร เครื่องมือสองชิ้นแสดงเลเยอร์ที่มองเห็นได้ชัดเจน
ประเด็นสำคัญ: เข้ารหัสสำหรับ URL, Escape สำหรับเอาต์พุต — วิธีที่ตัวเข้ารหัสและตัวถอดรหัส URL และตัว Escape เอนทิตี HTML นั่งเคียงข้างกันในผลิตภัณฑ์เดียวสำหรับงานสองงานที่แตกต่างกัน
ประเด็นสำคัญคือการเข้ารหัสและการ Escape เป็นข้อกังวลที่แยกจากกันในเลเยอร์ที่แตกต่างกันโดยสิ้นเชิง การเข้ารหัส URL ปกป้องโครงสร้างที่ส่งเท่านั้น การ Escape เอาต์พุตจะป้องกันเนื้อหาที่แสดงผล ค่าที่เข้ารหัสอย่างถูกต้องยังคงต้องมีการ Escape เอาต์พุตเมื่อถึง HTML สตริงที่ยกเว้นอย่างถูกต้องไม่จำเป็นต้องเข้ารหัส URL หากไม่ได้ใส่ลงใน URL
ใช้การป้องกันที่ถูกต้องในชั้นที่ถูกต้องอย่างแท้จริง อย่าพึ่งพาการเข้ารหัส URL เพื่อหยุดการโจมตี XSS อย่าพึ่งพาการหลบหนี HTML เพื่อรักษาโครงสร้าง URL ทำความเข้าใจกระแสข้อมูลของคุณและใช้การเปลี่ยนแปลงที่เหมาะสมในแต่ละขั้นตอน URL ตัวเข้ารหัสช่วยให้คุณเห็นว่าการเข้ารหัสทำอะไร จากนั้นใช้ HTML เอนทิตี Escape สำหรับขั้นตอนเอาต์พุต