เกี่ยวกับคำตอบที่มีประโยชน์มากมายฉันหวังว่าจะเพิ่มคุณค่าให้กับเธรดนี้
การฉีด SQL คือการโจมตีที่สามารถทำได้ผ่านอินพุตของผู้ใช้ (อินพุตที่กรอกโดยผู้ใช้และจากนั้นใช้ภายในแบบสอบถาม) รูปแบบการฉีด SQL เป็นไวยากรณ์เคียวรีที่ถูกต้องในขณะที่เราเรียกได้ว่า: คิวรี่ไม่ถูกต้องสำหรับเหตุผลที่ไม่ดีและเราคิดว่าอาจมีบุคคลที่ไม่ดีที่พยายามรับข้อมูลลับ (ผ่านการควบคุมการเข้าถึง) ที่มีผลต่อหลักการความปลอดภัยสามประการ ความสมบูรณ์และความพร้อมใช้งาน)
ตอนนี้จุดของเราคือการป้องกันภัยคุกคามด้านความปลอดภัยเช่นการโจมตีการฉีด SQL คำถามที่ถาม (วิธีการป้องกันการโจมตีการฉีด SQL โดยใช้ PHP) เป็นจริงมากขึ้นการกรองข้อมูลหรือการล้างข้อมูลอินพุตเป็นกรณีเมื่อใช้ข้อมูลผู้ใช้ภายใน แบบสอบถามดังกล่าวการใช้ PHP หรือภาษาการเขียนโปรแกรมอื่น ๆ ไม่ใช่กรณีหรือตามคำแนะนำของผู้คนจำนวนมากให้ใช้เทคโนโลยีที่ทันสมัยเช่นคำสั่งที่เตรียมไว้หรือเครื่องมืออื่น ๆ ที่สนับสนุนการป้องกันการฉีด SQL ในปัจจุบันพิจารณาว่าเครื่องมือเหล่านี้ไม่มีอีกแล้ว? คุณรักษาความปลอดภัยแอปพลิเคชันของคุณอย่างไร?
วิธีการของฉันกับการฉีด SQL คือ: การล้างข้อมูลที่ผู้ใช้ป้อนก่อนที่จะส่งไปยังฐานข้อมูล (ก่อนที่จะใช้ภายในแบบสอบถามใด ๆ )
การกรองข้อมูลสำหรับ (การแปลงข้อมูลที่ไม่ปลอดภัยเป็นข้อมูลที่ปลอดภัย)
พิจารณาว่าPDOและMySQLiไม่พร้อมใช้งาน คุณจะรักษาความปลอดภัยใบสมัครของคุณได้อย่างไร? คุณบังคับให้ฉันใช้พวกเขาหรือไม่? แล้วภาษาอื่นที่ไม่ใช่ PHP ล่ะ ฉันชอบที่จะเสนอแนวคิดทั่วไปเนื่องจากสามารถใช้สำหรับเส้นขอบที่กว้างกว่าไม่ใช่เฉพาะภาษาที่เฉพาะเจาะจง
- ผู้ใช้ SQL (จำกัด สิทธิ์ของผู้ใช้): การดำเนินการ SQL ทั่วไปส่วนใหญ่คือ (SELECT, UPDATE, INSERT) แล้วทำไมจึงให้สิทธิ์ UPDATE แก่ผู้ใช้ที่ไม่ต้องการ ตัวอย่างเช่นหน้าการเข้าสู่ระบบและการค้นหาใช้เพียง SELECT จากนั้นเหตุใดจึงใช้ผู้ใช้ DB ในหน้าเหล่านี้ด้วยสิทธิ์ระดับสูง
RULE: ห้ามสร้างผู้ใช้ฐานข้อมูลหนึ่งรายสำหรับสิทธิ์ทั้งหมด สำหรับการดำเนินงาน SQL ทั้งหมดคุณสามารถสร้างแบบแผนของคุณเช่น (ตัวเลือกตัวเลือกตัวปรับปรุง) เป็นชื่อผู้ใช้เพื่อการใช้งานที่ง่าย
ดูหลักการของสิทธิน้อย
การกรองข้อมูล: ก่อนสร้างการป้อนข้อมูลผู้ใช้แบบสอบถามใด ๆ ควรตรวจสอบและกรอง สำหรับโปรแกรมเมอร์มันเป็นสิ่งสำคัญที่จะกำหนดคุณสมบัติบางอย่างสำหรับแต่ละตัวแปรที่ใช้การป้อนข้อมูล:
ชนิดข้อมูลรูปแบบข้อมูลและความยาวของข้อมูล เขตข้อมูลที่เป็นตัวเลขระหว่าง (x และ y) จะต้องได้รับการตรวจสอบความถูกต้องโดยใช้กฎที่แน่นอนและสำหรับเขตข้อมูลที่เป็นสตริง (ข้อความ): รูปแบบเป็นกรณีตัวอย่างเช่นชื่อผู้ใช้จะต้องมีอักขระบางตัวเท่านั้น พูด [a-zA-Z0-9_-.] ความยาวแตกต่างกันระหว่าง (x และ n) โดยที่ x และ n (จำนวนเต็ม, x <= n)
กฎ: การสร้างตัวกรองและกฎการตรวจสอบที่ถูกต้องเป็นแนวทางปฏิบัติที่ดีที่สุดสำหรับฉัน
ใช้เครื่องมืออื่น ๆ : ที่นี่ฉันจะเห็นด้วยกับคุณว่าคำสั่งที่เตรียมไว้ (แบบสอบถามแบบใช้พารามิเตอร์) และขั้นตอนการจัดเก็บ ข้อเสียของที่นี่คือวิธีเหล่านี้ต้องการทักษะขั้นสูงซึ่งไม่มีอยู่สำหรับผู้ใช้ส่วนใหญ่ แนวคิดพื้นฐานที่นี่คือการแยกความแตกต่างระหว่างแบบสอบถาม SQL และข้อมูลที่ใช้ภายใน ทั้งสองวิธีสามารถใช้ได้แม้กับข้อมูลที่ไม่ปลอดภัยเนื่องจากข้อมูลที่ผู้ใช้ป้อนที่นี่ไม่ได้เพิ่มสิ่งใด ๆ ลงในคิวรีดั้งเดิมเช่น (ใด ๆ หรือ x = x)
สำหรับข้อมูลเพิ่มเติมโปรดอ่านOWASP SQL Injection ป้องกันโกงแผ่น
ตอนนี้ถ้าคุณเป็นผู้ใช้ขั้นสูงให้เริ่มใช้การป้องกันแบบนี้ตามที่คุณต้องการ แต่สำหรับผู้เริ่มต้นหากพวกเขาไม่สามารถใช้ขั้นตอนการจัดเก็บและจัดทำคำสั่งได้อย่างรวดเร็ว
ในที่สุดลองพิจารณาว่าผู้ใช้ส่งข้อความด้านล่างนี้แทนที่จะป้อนชื่อผู้ใช้ของเขา / เธอ:
[1] UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = 'root'
อินพุตนี้สามารถตรวจสอบได้ล่วงหน้าโดยไม่ต้องมีคำสั่งที่เตรียมไว้และขั้นตอนการจัดเก็บ แต่จะอยู่ในด้านที่ปลอดภัยโดยใช้พวกเขาเริ่มต้นหลังจากการกรองข้อมูลผู้ใช้และการตรวจสอบ
จุดสุดท้ายคือการตรวจจับพฤติกรรมที่ไม่คาดคิดซึ่งต้องใช้ความพยายามและความซับซ้อนมากขึ้น ไม่แนะนำให้ใช้กับเว็บแอปพลิเคชันทั่วไป
พฤติกรรมที่ไม่คาดคิดในอินพุตผู้ใช้ด้านบนคือ SELECT, UNION, IF, SUBSTRING, BENCHMARK, SHA และ root เมื่อตรวจพบคำเหล่านี้คุณสามารถหลีกเลี่ยงการป้อนข้อมูล
อัปเดต 1:
ผู้ใช้แสดงความคิดเห็นว่าโพสต์นี้ไร้ประโยชน์ OK! นี่คือสิ่งที่OWASP.ORG จัดหาให้ :
ป้องกันหลัก:
# 1 ตัวเลือก: การใช้งบเตรียม (Parameterized แบบสอบถาม)
ตัวเลือกที่ 2: การใช้วิธีการจัดเก็บ
ตัวเลือก # 3: หนีทั้งหมดผู้ใช้ที่ป้อนข้อมูล
การป้องกันเพิ่มเติม:
นอกจากนี้ยังบังคับใช้: Privilege น้อย
นอกจากนี้ยังดำเนินการ: รายชื่อสีขาวป้อนข้อมูลการตรวจสอบ
ดังที่คุณทราบการอ้างว่าบทความควรได้รับการสนับสนุนจากอาร์กิวเมนต์ที่ถูกต้องอย่างน้อยหนึ่งรายการ! มิฉะนั้นจะถือเป็นการโจมตีและการเรียกร้องที่ไม่ดี!
อัปเดต 2:
จากคู่มือ PHP, PHP: ข้อความสั่งเตรียมการ - คู่มือ :
การหลบหนีและการฉีด SQL
ตัวแปรที่ถูกผูกไว้จะหนีโดยอัตโนมัติโดยเซิร์ฟเวอร์ เซิร์ฟเวอร์จะแทรกค่า Escape ที่ตำแหน่งที่เหมาะสมลงในเทมเพลตคำสั่งก่อนดำเนินการ ต้องให้คำแนะนำแก่เซิร์ฟเวอร์สำหรับประเภทของตัวแปรที่ผูกไว้เพื่อสร้างการแปลงที่เหมาะสม ดูฟังก์ชัน mysqli_stmt_bind_param () สำหรับข้อมูลเพิ่มเติม
บางครั้งการหลีกเลี่ยงค่าภายในเซิร์ฟเวอร์จะถือเป็นคุณลักษณะด้านความปลอดภัยเพื่อป้องกันการฉีด SQL การรักษาความปลอดภัยระดับเดียวกันสามารถทำได้ด้วยคำสั่งที่ไม่ได้เตรียมไว้หากค่าอินพุตถูกหลีกเลี่ยงอย่างถูกต้อง
อัปเดต 3:
ฉันสร้างกรณีทดสอบเพื่อทราบว่า PDO และ MySQLi ส่งแบบสอบถามไปยังเซิร์ฟเวอร์ MySQL อย่างไรเมื่อใช้คำสั่งที่เตรียมไว้:
PDO:
$user = "''1''"; // Malicious keyword
$sql = 'SELECT * FROM awa_user WHERE userame =:username';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':username' => $user));
บันทึกการสืบค้น:
189 Query SELECT * FROM awa_user WHERE userame ='\'\'1\'\''
189 Quit
MySQLi:
$stmt = $mysqli->prepare("SELECT * FROM awa_user WHERE username =?")) {
$stmt->bind_param("s", $user);
$user = "''1''";
$stmt->execute();
บันทึกการสืบค้น:
188 Prepare SELECT * FROM awa_user WHERE username =?
188 Execute SELECT * FROM awa_user WHERE username ='\'\'1\'\''
188 Quit
เป็นที่ชัดเจนว่าคำสั่งที่เตรียมไว้นั้นกำลังหลบหนีข้อมูลอยู่
ดังที่ได้กล่าวไว้ในข้อความข้างต้น
บางครั้งการหลีกเลี่ยงค่าภายในเซิร์ฟเวอร์จะถือเป็นคุณลักษณะด้านความปลอดภัยเพื่อป้องกันการฉีด SQL การรักษาความปลอดภัยระดับเดียวกันสามารถทำได้ด้วยคำสั่งที่ไม่ได้เตรียมไว้หากค่าอินพุตถูกหลบหนีอย่างถูกต้อง
ดังนั้นนี่เป็นการพิสูจน์ว่าการตรวจสอบข้อมูลเช่นเป็นintval()
ความคิดที่ดีสำหรับค่าจำนวนเต็มก่อนที่จะส่งแบบสอบถามใด ๆ นอกจากนี้การป้องกันข้อมูลของผู้ใช้ที่เป็นอันตรายก่อนที่จะส่งแบบสอบถามเป็นวิธีการที่ถูกต้องและถูกต้อง
โปรดดูคำถามนี้สำหรับรายละเอียดเพิ่มเติม: PDO ส่งแบบสอบถามดิบไปยัง MySQL ในขณะที่ Mysqli ส่งแบบสอบถามที่เตรียมไว้ทั้งคู่ให้ผลลัพธ์เดียวกัน
อ้างอิง:
- แผ่นโกง SQL Injection
- การฉีด SQL
- ความปลอดภัยของข้อมูล
- หลักการรักษาความปลอดภัย
- การตรวจสอบข้อมูล