ปกป้องอินพุตผู้ใช้ของนิพจน์ทั่วไปจากการถูกโจมตี


9

ฉันรับรู้ถึงการปฏิเสธการแสดงผลปกติ (ReDoS) มีวิธีที่สมเหตุสมผลหรือไม่ที่จะอนุญาตให้ผู้ใช้สร้าง regexes ที่กำหนดเองในขณะที่รับประกันได้ว่าพวกเขาไม่ได้ส่งรูปแบบที่ช้าแบบเอ็กซ์โปเนนเชียล?


คุณกำลังขาดรายละเอียด แพลตฟอร์มการใช้งานและอื่น ๆ
whatsisname

8
แทนที่จะพยายามหลีกเลี่ยงผู้ใช้ที่ส่ง regex ที่ไม่ดีอาจเป็นวิธีแก้ปัญหาที่หลังจากยกเลิกช่วงเวลาหนึ่งไปแล้ว
ซามูเอล

คำตอบ:


8

ปัญหาของนิพจน์ทั่วไปไม่ใช่ regex นั้นเอง แต่เอ็นจิ้น regex ที่มีคุณสมบัติ "สะดวก" ทุกชนิดเช่นการย้อนรอย ดังนั้นการใช้เอ็นจิน regex ที่ไม่มีคุณสมบัติเหล่านี้จะหลีกเลี่ยง

การแสดงออกปกติแนวคิดวิทยาศาสตร์คอมพิวเตอร์สามารถจับคู่ในเวลาเชิงเส้นหลังจากที่พวกเขาจะรวบรวมไปยังเครื่องสถานะ จำกัด ดังนั้นเอ็นจิน regex ที่ทำงานด้วยเครื่องจักรจะไม่สามารถใช้สำหรับ ReDoS ได้ อย่างไรก็ตามเครื่องของรัฐที่จำเป็นอาจมีขนาดค่อนข้างใหญ่ในตัวอย่างทางพยาธิวิทยา แต่การ จำกัด หน่วยความจำที่มีอยู่มักจะง่ายกว่าการ จำกัด เวลาการคำนวณที่มีอยู่

เครื่องยนต์ RE2ได้รับการพัฒนาโดยเฉพาะการจัดการกับ regexes ที่ไม่น่าเชื่อถือและได้รับการออกแบบสำหรับการดำเนินการเชิงเส้นเวลา

อีกทางเลือกหนึ่งคือการรวบรวม regexes ด้วยตัวคุณเองจากสัญกรณ์ที่ง่ายขึ้น ตัวอย่างเช่นคุณอาจอนุญาตให้ผู้ใช้ใช้รูปแบบ glob (เช่น*.txt) จากนั้นคุณสามารถแยกวิเคราะห์ได้ว่าในลักษณะที่ป้องกันการย้อนรอยเช่นโดยไม่อนุญาตให้ทำรังและใช้ปริมาณโลภเท่านั้น สำหรับกรณีการใช้งานจำนวนมากสัญกรณ์รูปแบบที่เรียบง่ายนั้นเพียงพอแล้ว


11

วิเคราะห์การแสดงออกปกติเพื่อดูว่ามันจะช้าหรือไม่โดยไม่ต้องวิเคราะห์กลายเป็นตัวช้าจำนวนการแก้ปัญหาการหยุดชะงัก ในคำอื่น ๆ มันเป็นไปไม่ได้ที่จะหาวิธีการแก้ปัญหาที่ถูกต้องและครบถ้วน

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


3
คุณมีการอ้างอิงสำหรับคำสั่งแรกของคุณหรือไม่? ฉันสนใจที่จะเห็นหลักฐานดังกล่าว Regexes ไม่ได้ทำการทัวริงให้เสร็จสมบูรณ์ดังนั้นปัญหาการหยุดชะงักอาจไม่สามารถใช้ได้
เซบาสเตียนเรดล

3
@SebastianRedl เป็นเรื่องจริงที่การพูดอย่างเคร่งครัดนิพจน์ทั่วไปไม่ได้ทำให้ทัวริงสมบูรณ์ แต่ไลบรารี Regex ทั้งหมดที่ใช้กันอย่างแพร่หลายนั้นมีส่วนขยายที่ทำให้พวกมันไม่เป็นปกติอีกต่อไป การ จำกัด ผู้ใช้ของคุณให้มีการแสดงออกปกติอย่างแท้จริงอาจเป็นทางออกที่ดีสำหรับสถานการณ์นี้
Kilian Foth

2
@KilianFoth: IIRC แม้แต่การแสดงออกปกติที่แท้จริง (ในความหมายของคำ CompSci) อาจต้องการการย้อนรอยจำนวนมาก แต่เนื่องจากมันไม่ได้เป็นทัวริงที่สมบูรณ์สำหรับ regex ที่ให้มาจึงเป็นไปได้ในทางทฤษฎีที่จะสร้างขอบเขตบนนี้ อย่างไรก็ตามปัญหานี้เปิดสองปัญหา: การกำหนดขอบเขตบนโดยอัตโนมัติเป็นงานที่ไม่สำคัญและผลลัพธ์อาจให้ผลลัพธ์ที่ไม่สมเหตุผล (เช่นในขอบเขตบนสูงกว่าเวลาที่คาดหวังมาก)
MSalters

@msalters การแสดงออกปกติใด ๆ ที่แท้จริงสามารถเปลี่ยนแปลงได้โดยอัตโนมัติทางกลไกไปยังสถานะ จำกัด อัตโนมัติของเครื่องจักรนั่นก็คือมันเป็นไปได้เสมอที่จะจับคู่การแสดงออกโดยไม่ย้อนกลับเลย แน่นอนว่า FSA ของคุณมีขนาดใหญ่เกินสมควร แต่นั่นแสดงให้เห็นว่าการ จำกัด จำนวนรัฐใน FSA ที่สร้างขึ้นนั้นเป็นวิธีการที่เพียงพอในการป้องกันการโจมตีที่เป็นปัญหา
Jules

1

ในฐานะผู้เขียนโปรแกรมแยกวิเคราะห์สำหรับโครงการลาซารัสฉันจะบอกว่าไม่มีวิธีที่จะเข้าใจการแสดงออกปกติใด ๆ ที่กำหนดว่าจะใช้ทรัพยากรใดในข้อความที่กำหนด

โดยไม่ต้องใช้ทรัพยากรเดียวกันฉันหมายถึง (อย่างน้อยในความหมายใหญ่)

ดังนั้นวิธีที่ดีที่สุด - รันโปรแกรมวิเคราะห์คำในเธรดแยกและฆ่ามันหลังจากหมดเวลา


0

นอกเหนือจากคำตอบอื่น ๆ แล้วโซลูชันอาจจะม้วนไลบรารี regex ของคุณเองที่อนุญาตให้ใช้เครื่องมือวัดประสิทธิภาพในระหว่างการดำเนินการและทำให้มีวิธีการฆ่าการดำเนินการครึ่งทางหากตรงตามเกณฑ์บางประการ

ในทำนองเดียวกันคุณสามารถเรียกใช้ regexes บนเธรดอื่นและฆ่าเธรดหากใช้เวลานานเกินไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.