การฉีด SQL ในฟังก์ชัน Postgres กับเคียวรีที่เตรียมไว้


30

ใน Postgres แบบสอบถามที่เตรียมไว้และฟังก์ชั่นที่ผู้ใช้กำหนดเองนั้นเทียบเท่ากับกลไกในการป้องกันการฉีด SQLหรือไม่
มีข้อดีโดยเฉพาะอย่างยิ่งในแนวทางหนึ่งมากกว่าอีกวิธีหนึ่งหรือไม่?

คำตอบ:


36

มันขึ้นอยู่กับ.

ฟังก์ชัน SQL

ด้วยLANGUAGE sqlคำตอบคือโดยทั่วไปใช่

พารามิเตอร์ Passed ถือเป็นค่าและไม่สามารถฉีด SQL ได้ตราบใดที่คุณไม่เรียกใช้ฟังก์ชันที่ไม่ปลอดภัยจากพารามิเตอร์bodyและ pass

ฟังก์ชัน PL / pgSQL

ด้วยLANGUAGE plpgsqlคำตอบคือปกติใช่

อย่างไรก็ตาม , PL / pgSQL ช่วยให้SQL แบบไดนามิกที่ผ่านพารามิเตอร์ (หรือบางส่วน) EXECUTEจะถูกตัดแบ่งเพื่อสตริงแบบสอบถามและดำเนินการด้วย นี้สามารถแปลงผู้ใช้ป้อนรหัส SQL และทำให้ฉีด SQL ที่เป็นไปได้ คุณไม่สามารถบอกได้จากภายนอกว่าร่างกายของฟังก์ชั่นจัดการกับมันอย่างถูกต้องหรือไม่ มีเครื่องมือให้

ใช้ SQL แบบไดนามิกที่คุณต้องการเท่านั้น คำสั่ง SQL ธรรมดาที่ใช้พารามิเตอร์เป็นค่าปลอดภัยต่อการฉีด SQL เช่นฟังก์ชัน SQL

สำหรับSQL แบบไดนามิกควรส่งค่าเป็นค่าด้วย:

  • USINGข้อ ตัวอย่าง

ทำให้การฉีด SQL เป็นไปไม่ได้บนหลักการ

หากคุณต่อค่าเข้าด้วยกันในสตริง SQL ให้ใช้:

ห่อสตริงในเครื่องหมายคำพูดเดี่ยวอย่างปลอดภัยจึงหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์และการฉีด SQL

พารามิเตอร์กระบวนการที่จะถือว่าเป็นตัวระบุในสตริง SQL ด้วย:

ล้อมรอบสตริงในเครื่องหมายคำพูดคู่อย่างปลอดภัยเมื่อจำเป็นดังนั้นจึงหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์และการฉีด SQL

ที่เกี่ยวข้อง:

ไม่เพียงแค่สร้างสตริงจากอินพุตของผู้ใช้และดำเนินการ ซึ่งรวมถึงตัวระบุส่งผ่านโดยตรงจากผู้ใช้หรือเรียกจากแคตตาล็อกระบบ ทั้งหมดจะต้องได้รับการปฏิบัติเช่นการป้อนข้อมูลของผู้ใช้และยกมาอย่างปลอดภัยเมื่อสร้าง SQL แบบไดนามิก!

เพิ่มเติมเกี่ยวกับผลกระทบของประสิทธิภาพในคำตอบที่เกี่ยวข้องนี้:

พื้นฐานเกี่ยวกับการฉีด SQL:

ข้อพิจารณาที่คล้ายกันนี้ใช้กับภาษาฝั่งเซิร์ฟเวอร์อื่นที่อนุญาต SQL แบบไดนามิก


ดังนั้นโดยสรุป: ถ้า 1) ฉันใช้ภาษา sql เท่านั้นฉันปลอดภัย 2) ถ้าฉันใช้ plpgslq แต่ไม่ได้ดำเนินการฉันปลอดภัย 3) ถ้าฉันใช้ plpgsql และดำเนินการ แต่ไม่มีตัวระบุและ% s หรือ% L ตามความเหมาะสมฉันปลอดภัยหรือ 4) ถ้าฉันใช้ plpgsql และดำเนินการและตัวระบุ แต่% I หรือ quote_ident ตามความเหมาะสมฉันปลอดภัย แก้ไข?
mickeyf_supports_Monica

@mickeyf: โดยทั่วไปใช่ นอกจากนี้ให้ใช้USINGข้อสำหรับส่งค่าไปยังEXECUTEเมื่อใดก็ตามที่เป็นไปได้ คุณสามารถเรียกใช้ฟังก์ชัน PL / pgSQL จากภายในฟังก์ชัน SQL และส่งผ่านพารามิเตอร์ ดังนั้นเพื่อให้ถูกต้องอย่างแท้จริงคุณจะปลอดภัยตราบใดที่คุณไม่เรียกใช้ฟังก์ชันที่ไม่ปลอดภัยไม่ว่าโดยตรงหรือโดยอ้อม หากฟังก์ชั่นทั้งหมดของคุณทำอย่างถูกต้องนั่นจะไม่เกิดขึ้น
Erwin Brandstetter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.