กระบวนงานที่เก็บไว้ไม่ได้ป้องกันการฉีด SQL อย่างน่าอัศจรรย์ แต่มันจะป้องกันได้ง่ายกว่ามาก สิ่งที่คุณต้องทำคือสิ่งต่อไปนี้ (ตัวอย่าง Postgres):
CREATE OR REPLACE FUNCTION my_func (
IN in_user_id INT
)
[snip]
SELECT user_id, name, address FROM my_table WHERE user_id = in_user_id; --BAM! SQL INJECTION IMMUNE!!
[snip]
แค่นั้นแหละ! ปัญหาเกิดขึ้นเมื่อสร้างแบบสอบถามผ่านการต่อสตริง (เช่นไดนามิก SQL) และแม้แต่ในกรณีเหล่านั้นคุณอาจสามารถผูก! (ขึ้นอยู่กับฐานข้อมูล)
วิธีหลีกเลี่ยงการฉีด SQL ในคิวรีแบบไดนามิกของคุณ:
ขั้นตอนที่ 1) ถามตัวเองว่าคุณต้องการคิวรีแบบไดนามิกหรือไม่ หากคุณรวมสตริงเข้าด้วยกันเพียงเพื่อตั้งค่าอินพุตแสดงว่าคุณอาจทำผิด (มีข้อยกเว้นสำหรับกฎนี้ - ข้อยกเว้นอย่างหนึ่งคือการรายงานคิวรีบนฐานข้อมูลบางอย่างคุณอาจมีปัญหาด้านประสิทธิภาพหากคุณไม่บังคับให้คอมไพล์แบบสอบถามใหม่ด้วยการดำเนินการแต่ละครั้ง แต่วิจัยปัญหานี้ก่อนที่จะข้ามไป )
ขั้นตอนที่ 2) วิจัยวิธีที่เหมาะสมในการตั้งค่าตัวแปรสำหรับ RDBMS เฉพาะของคุณ ตัวอย่างเช่น Oracle ช่วยให้คุณทำสิ่งต่อไปนี้ (อ้างอิงจากเอกสารของพวกเขา):
sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE '
|| v_column || ' = :2';
EXECUTE IMMEDIATE sql_stmt USING amount, column_value; --INJECTION IMMUNE!!
ที่นี่คุณยังไม่ได้เชื่อมต่ออินพุต คุณผูกมัดอย่างปลอดภัย! ไชโย!
หากฐานข้อมูลของคุณไม่รองรับสิ่งที่กล่าวมาข้างต้น (หวังว่าจะไม่มีสิ่งใดในพวกเขาที่ยังไม่ดี แต่ฉันจะไม่แปลกใจ) - หรือถ้าคุณยังต้องเชื่อมต่อข้อมูลของคุณ (เช่นในกรณี "แบบสอบถาม" รายงาน ฉันพูดตามข้างบน) แล้วคุณต้องใช้ฟังก์ชั่นการหลบหนีที่เหมาะสม อย่าเขียนเอง ตัวอย่างเช่น postgres ให้ฟังก์ชัน quote_literal () ดังนั้นคุณจะทำงาน:
sql_stmt := 'SELECT salary FROM employees WHERE name = ' || quote_literal(in_name);
วิธีนี้หาก in_name เป็นสิ่งที่คดเคี้ยวเช่น '[snip] หรือ 1 = 1' (ส่วน "หรือ 1 = 1" หมายถึงเลือกแถวทั้งหมดช่วยให้ผู้ใช้เห็นเงินเดือนที่เขาไม่ควร!) แล้ว quote_literal ช่วยลดก้นของคุณด้วย ทำให้สตริงผลลัพธ์:
SELECT salary FROM employees WHERE name = '[snip] or 1=1'
จะไม่พบผลลัพธ์ใด ๆ (เว้นแต่คุณจะมีพนักงานบางคนที่มีชื่อแปลก ๆ )
นั่นคือส่วนสำคัญของมัน! ตอนนี้ฉันจะปล่อยให้คุณมีลิงค์ไปยังโพสต์คลาสสิกโดย Oracle guru Tom Kyte ในเรื่องของ SQL Injection เพื่อขับเคลื่อนจุดกลับบ้าน: Linky