คำตอบอื่น ๆ ครอบคลุมสิ่งที่คุณต้องรู้อยู่แล้ว แต่อาจจะช่วยชี้แจงเพิ่มเติมได้บ้าง:
มีสองสิ่งที่คุณต้องทำ:
1. ตรวจสอบข้อมูลแบบฟอร์ม
ดังที่คำตอบของ Jonathan Hobbsแสดงให้เห็นอย่างชัดเจนการเลือกองค์ประกอบ html สำหรับการป้อนข้อมูลแบบฟอร์มไม่ได้ทำการกรองที่เชื่อถือได้สำหรับคุณ
โดยปกติการตรวจสอบความถูกต้องจะทำในลักษณะที่ไม่เปลี่ยนแปลงข้อมูล แต่จะแสดงแบบฟอร์มอีกครั้งโดยมีการระบุฟิลด์ว่า "โปรดแก้ไขสิ่งนี้"
เฟรมเวิร์กและ CMS ส่วนใหญ่มีตัวสร้างฟอร์มที่ช่วยคุณในงานนี้ และไม่ใช่แค่นั้นพวกเขายังช่วยต่อต้าน CSRF (หรือ "XSRF") ซึ่งเป็นการโจมตีอีกรูปแบบหนึ่ง
2. Sanitize / Escape ตัวแปรในคำสั่ง SQL ..
.. หรือปล่อยให้งบที่เตรียมไว้ทำงานแทนคุณ.
หากคุณสร้างคำสั่ง SQL (ของฉัน) ด้วยตัวแปรใด ๆ ที่ผู้ใช้ระบุหรือไม่คุณจำเป็นต้องหลีกเลี่ยงและอ้างถึงตัวแปรเหล่านี้
โดยทั่วไปตัวแปรใด ๆ ที่คุณแทรกลงในคำสั่ง MySQL ควรเป็นสตริงหรือสิ่งที่ PHP สามารถเปลี่ยนเป็นสตริงที่ MySQL สามารถแยกย่อยได้อย่างน่าเชื่อถือ เช่นตัวเลข
สำหรับสตริงคุณต้องเลือกหนึ่งในหลายวิธีเพื่อหลีกเลี่ยงสตริงซึ่งหมายความว่าแทนที่อักขระใด ๆ ที่อาจมีผลข้างเคียงใน MySQL
- ใน MySQL + PHP แบบเก่า mysql_real_escape_string () จะทำงาน ปัญหาคือมันง่ายเกินไปที่จะลืมดังนั้นคุณควรใช้คำสั่งที่เตรียมไว้หรือเครื่องมือสร้างแบบสอบถาม
- ใน MySQLi คุณสามารถใช้คำสั่งที่เตรียมไว้
- เฟรมเวิร์กและ CMS ส่วนใหญ่มีตัวสร้างคิวรีที่ช่วยคุณในงานนี้
หากคุณกำลังจัดการกับตัวเลขคุณสามารถละเว้นการหลีกเลี่ยงและเครื่องหมายคำพูด (นี่คือสาเหตุที่ข้อความที่เตรียมไว้อนุญาตให้ระบุประเภท)
สิ่งสำคัญคือต้องชี้ให้เห็นว่าคุณหลีกเลี่ยงตัวแปรสำหรับคำสั่ง SQL และไม่ใช่สำหรับฐานข้อมูลเองและไม่ได้สำหรับฐานข้อมูลของตัวเอง ฐานข้อมูลจะจัดเก็บสตริงดั้งเดิม แต่คำสั่งต้องการเวอร์ชันที่ใช้ Escape
จะเกิดอะไรขึ้นถ้าคุณละเว้นสิ่งใดสิ่งหนึ่งเหล่านี้
หากคุณไม่ได้ใช้การตรวจสอบความถูกต้องของฟอร์มแต่คุณทำความสะอาดอินพุต SQL ของคุณคุณอาจเห็นสิ่งเลวร้ายทุกประเภทเกิดขึ้น แต่คุณจะไม่เห็นการแทรก SQL (*)
ขั้นแรกอาจทำให้ใบสมัครของคุณอยู่ในสถานะที่คุณไม่ได้วางแผนไว้ เช่นหากคุณต้องการคำนวณอายุเฉลี่ยของผู้ใช้ทั้งหมด แต่ผู้ใช้รายหนึ่งระบุอายุเป็น "aljkdfaqer" การคำนวณของคุณจะล้มเหลว
ประการที่สองอาจมีการโจมตีด้วยการฉีดอื่น ๆ ทุกประเภทที่คุณต้องพิจารณาเช่นอินพุตของผู้ใช้อาจมีจาวาสคริปต์หรือสิ่งอื่น ๆ
ยังคงมีปัญหากับฐานข้อมูลเช่นถ้าเขตข้อมูล (คอลัมน์ตารางฐานข้อมูล) จำกัด ไว้ที่ 255 อักขระและสตริงยาวกว่านั้น หรือถ้าฟิลด์ยอมรับเฉพาะตัวเลขและคุณพยายามบันทึกสตริงที่ไม่ใช่ตัวเลขแทน แต่นี่ไม่ใช่ "การฉีด" แต่เป็นเพียง "การขัดข้องของแอปพลิเคชัน"
แต่แม้ว่าคุณจะมีฟิลด์ข้อความว่างที่คุณอนุญาตให้ป้อนข้อมูลใด ๆ โดยไม่มีการตรวจสอบความถูกต้องเลยคุณยังคงสามารถบันทึกข้อมูลนี้ลงในฐานข้อมูลได้เช่นเดียวกับที่คุณต้องหลีกเลี่ยงอย่างถูกต้องเมื่อไปที่คำสั่งฐานข้อมูล ปัญหาเกิดขึ้นเมื่อคุณต้องการใช้สตริงนี้ที่ใดที่หนึ่ง
(*) หรือนี่จะเป็นอะไรที่แปลกใหม่จริงๆ
หากคุณไม่ได้หลบหนีตัวแปรสำหรับคำสั่ง SQLแต่คุณตรวจสอบความถูกต้องของการป้อนข้อมูลในรูปแบบแล้วคุณยังคงเห็นสิ่งที่ไม่ดีเกิดขึ้น
ขั้นแรกคุณต้องเสี่ยงว่าเมื่อคุณบันทึกข้อมูลลงในฐานข้อมูลและโหลดอีกครั้งข้อมูลนั้นจะไม่เป็นข้อมูลเดิมอีกต่อไป "สูญหายในการแปล"
ประการที่สองอาจส่งผลให้คำสั่ง SQL ไม่ถูกต้องและทำให้แอปพลิเคชันของคุณขัดข้อง เช่นหากตัวแปรใด ๆ มีเครื่องหมายอัญประกาศหรือเครื่องหมายอัญประกาศคู่ขึ้นอยู่กับประเภทของใบเสนอราคาที่คุณใช้คุณจะได้รับคำสั่ง MySQL ที่ไม่ถูกต้อง
ประการที่สามยังสามารถทำให้เกิดการฉีด SQL
หากข้อมูลที่ผู้ใช้ของคุณป้อนจากแบบฟอร์มได้รับการกรอง / ตรวจสอบความถูกต้องแล้วการฉีด SQl โดยเจตนาอาจมีโอกาสน้อยลงหากข้อมูลของคุณลดลงเป็นรายการตัวเลือกแบบฮาร์ดโค้ดหรือหากถูก จำกัด ไว้ที่ตัวเลข แต่สามารถใช้การป้อนข้อความฟรีสำหรับการแทรก SQL ได้หากคุณไม่ได้หลีกเลี่ยงตัวแปรในคำสั่ง SQL อย่างถูกต้อง
และแม้ว่าคุณจะไม่มีการป้อนแบบฟอร์มเลยคุณก็ยังสามารถมีสตริงจากแหล่งข้อมูลทุกประเภท: อ่านจากระบบไฟล์, คัดลอกจากอินเทอร์เน็ตเป็นต้นไม่มีใครสามารถรับประกันได้ว่าสตริงเหล่านี้ปลอดภัย
<select>
การป้อนข้อมูล แม้แต่ผู้ใช้ทางเทคนิคเล็กน้อยก็สามารถเพิ่มตัวเลือกเพิ่มเติมได้โดยใช้คอนโซลเบราว์เซอร์ หากคุณเก็บรายการที่อนุญาตพิเศษของอาร์เรย์ของค่าที่มีอยู่และเปรียบเทียบอินพุตกับมันคุณสามารถลดค่านั้นได้ (และคุณควรจะป้องกันค่าที่ไม่ต้องการ)