ใน Postgres แบบสอบถามที่เตรียมไว้และฟังก์ชั่นที่ผู้ใช้กำหนดเองนั้นเทียบเท่ากับกลไกในการป้องกันการฉีด SQLหรือไม่
มีข้อดีโดยเฉพาะอย่างยิ่งในแนวทางหนึ่งมากกว่าอีกวิธีหนึ่งหรือไม่?
ใน Postgres แบบสอบถามที่เตรียมไว้และฟังก์ชั่นที่ผู้ใช้กำหนดเองนั้นเทียบเท่ากับกลไกในการป้องกันการฉีด SQLหรือไม่
มีข้อดีโดยเฉพาะอย่างยิ่งในแนวทางหนึ่งมากกว่าอีกวิธีหนึ่งหรือไม่?
คำตอบ:
มันขึ้นอยู่กับ.
ด้วยLANGUAGE sql
คำตอบคือโดยทั่วไปใช่
พารามิเตอร์ Passed ถือเป็นค่าและไม่สามารถฉีด SQL ได้ตราบใดที่คุณไม่เรียกใช้ฟังก์ชันที่ไม่ปลอดภัยจากพารามิเตอร์bodyและ pass
ด้วยLANGUAGE plpgsql
คำตอบคือปกติใช่
อย่างไรก็ตาม , PL / pgSQL ช่วยให้SQL แบบไดนามิกที่ผ่านพารามิเตอร์ (หรือบางส่วน) EXECUTE
จะถูกตัดแบ่งเพื่อสตริงแบบสอบถามและดำเนินการด้วย นี้สามารถแปลงผู้ใช้ป้อนรหัส SQL และทำให้ฉีด SQL ที่เป็นไปได้ คุณไม่สามารถบอกได้จากภายนอกว่าร่างกายของฟังก์ชั่นจัดการกับมันอย่างถูกต้องหรือไม่ มีเครื่องมือให้
ใช้ SQL แบบไดนามิกที่คุณต้องการเท่านั้น คำสั่ง SQL ธรรมดาที่ใช้พารามิเตอร์เป็นค่าปลอดภัยต่อการฉีด SQL เช่นฟังก์ชัน SQL
สำหรับSQL แบบไดนามิกควรส่งค่าเป็นค่าด้วย:
ทำให้การฉีด SQL เป็นไปไม่ได้บนหลักการ
หากคุณต่อค่าเข้าด้วยกันในสตริง SQL ให้ใช้:
format()
ด้วยตัวระบุรูปแบบ %L
ที่มีรูปแบบระบุตัวอย่างquote_literal()
หรือ quote_nullable()
หรือตัวอย่างห่อสตริงในเครื่องหมายคำพูดเดี่ยวอย่างปลอดภัยจึงหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์และการฉีด SQL
พารามิเตอร์กระบวนการที่จะถือว่าเป็นตัวระบุในสตริง SQL ด้วย:
format()
%I
ที่มีรูปแบบระบุ ตัวอย่างตัวอย่างquote_ident()
. ตัวอย่างregclass
_tbl::regclass
ตัวอย่างล้อมรอบสตริงในเครื่องหมายคำพูดคู่อย่างปลอดภัยเมื่อจำเป็นดังนั้นจึงหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์และการฉีด SQL
ที่เกี่ยวข้อง:
ไม่เพียงแค่สร้างสตริงจากอินพุตของผู้ใช้และดำเนินการ ซึ่งรวมถึงตัวระบุส่งผ่านโดยตรงจากผู้ใช้หรือเรียกจากแคตตาล็อกระบบ ทั้งหมดจะต้องได้รับการปฏิบัติเช่นการป้อนข้อมูลของผู้ใช้และยกมาอย่างปลอดภัยเมื่อสร้าง SQL แบบไดนามิก!
เพิ่มเติมเกี่ยวกับผลกระทบของประสิทธิภาพในคำตอบที่เกี่ยวข้องนี้:
พื้นฐานเกี่ยวกับการฉีด SQL:
ข้อพิจารณาที่คล้ายกันนี้ใช้กับภาษาฝั่งเซิร์ฟเวอร์อื่นที่อนุญาต SQL แบบไดนามิก
USING
ข้อสำหรับส่งค่าไปยังEXECUTE
เมื่อใดก็ตามที่เป็นไปได้ คุณสามารถเรียกใช้ฟังก์ชัน PL / pgSQL จากภายในฟังก์ชัน SQL และส่งผ่านพารามิเตอร์ ดังนั้นเพื่อให้ถูกต้องอย่างแท้จริงคุณจะปลอดภัยตราบใดที่คุณไม่เรียกใช้ฟังก์ชันที่ไม่ปลอดภัยไม่ว่าโดยตรงหรือโดยอ้อม หากฟังก์ชั่นทั้งหมดของคุณทำอย่างถูกต้องนั่นจะไม่เกิดขึ้น