การป้องกัน SQL Injection
ป้องกันการโจมตีแบบฉีดคำสั่ง
การป้องกัน SQL Injection เป็นบทเรียน Cyber Security Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Cyber Security Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Cyber Security Academy มีบทเรียนทั้งหมด 4 บทเรียน
การฉีดคำสั่งเอสคิวแอลคืออะไร
การฉีดคำสั่งเอสคิวแอล (SQLi) เกิดขึ้นเมื่อข้อมูลนำเข้าจากผู้ใช้ที่ไม่น่าเชื่อถือถูกนำมาต่อเข้ากับคำสั่ง SQL โดยตรง ผู้โจมตีแอบแทรกไวยากรณ์ SQL ลงในช่องที่แอปพลิเคชันคาดว่าจะเป็นข้อมูลธรรมดา ทำให้ความหมายของคำสั่งเปลี่ยนไป
ช่องโหว่นี้ยังเป็นหนึ่งในช่องโหว่เว็บที่สร้างความเสียหายมากที่สุด เพราะอาจทำให้ข้อมูลทั้งฐานข้อมูลรั่วไหล ข้ามขั้นตอนการเข้าสู่ระบบ หรือทำลายข้อมูลได้
คำสั่งที่มีช่องโหว่
ข้อผิดพลาดแบบคลาสสิกคือการต่อสตริง หากข้อมูลนำเข้าคือ tom คำสั่งก็จะถูกต้อง แต่ข้อมูลนำเข้าที่ผู้โจมตีสร้างขึ้นจะเขียนตรรกะใหม่
- เครื่องหมายอัญประกาศเดี่ยวจะปิดสตริงก่อนถึงตำแหน่งที่ควรปิด
- ทุกอย่างหลังจากนั้นจะกลายเป็นคำสั่ง SQL ที่สามารถทำงานได้
query = "SELECT * FROM users WHERE name = '" + userInput + "'";
// userInput = tom' OR '1'='1
// becomes: SELECT * FROM users WHERE name = 'tom' OR '1'='1'การข้ามการยืนยันตัวตน
แบบฟอร์มเข้าสู่ระบบเป็นเป้าหมายสำคัญ ผู้โจมตีสามารถแทรกเงื่อนไขที่เป็นจริงเสมอและใส่เครื่องหมายให้ส่วนที่เหลือเป็นความคิดเห็น เพื่อเข้าสู่ระบบโดยไม่ต้องใช้รหัสผ่าน
ลำดับ -- จะทำให้ส่วนคำสั่งที่เหลือเป็นความคิดเห็น จึงไม่มีการตรวจสอบรหัสผ่าน
-- attacker enters in the username field:
admin' --
-- resulting query:
SELECT * FROM users WHERE user = 'admin' --' AND pass = '...'คำสั่งแบบกำหนดพารามิเตอร์
แนวป้องกันหลักคือคำสั่งแบบกำหนดพารามิเตอร์ (คำสั่งที่เตรียมไว้) โครงสร้าง SQL จะถูกส่งแยกจากข้อมูล ดังนั้นข้อมูลนำเข้าจะถูกมองว่าเป็นค่าเสมอ ไม่ใช่โค้ด
โปรแกรมควบคุมฐานข้อมูลจะผูกตัวแทน ? เข้ากับค่าที่ส่งมาอย่างปลอดภัย
-- Python (sqlite3 / psycopg)
cur.execute(
'SELECT * FROM users WHERE name = ? AND pass = ?',
(username, password)
)คำสั่งที่เตรียมไว้ใน Java
ภาษาหลักทุกภาษารองรับการกำหนดพารามิเตอร์ ใน Java ให้ใช้ PreparedStatement แทนการสร้างสตริงด้วย Statement
พารามิเตอร์ที่ผูกไว้จะไม่สามารถหลุดออกจากช่องของตนเองได้ ดังนั้นการฉีดคำสั่งจึงเป็นไปไม่ได้ในเชิงโครงสร้างสำหรับกรณีนี้
PreparedStatement ps = conn.prepareStatement(
"SELECT * FROM users WHERE name = ?");
ps.setString(1, userInput);
ResultSet rs = ps.executeQuery();กระบวนงานที่จัดเก็บไว้
กระบวนงานที่จัดเก็บไว้ช่วยได้เมื่อภายในกระบวนงานใช้ข้อมูลนำเข้าที่กำหนดพารามิเตอร์ แต่ควรระวัง กระบวนงานที่จัดเก็บไว้ซึ่งสร้าง SQL แบบไดนามิกด้วยการต่อสตริงก็มีช่องโหว่เช่นเดียวกัน
- ปลอดภัย: ส่งพารามิเตอร์ให้กระบวนงาน
- ไม่ปลอดภัย: ใช้
EXEC()กับสตริงที่ต่อกันภายในกระบวนงาน
การตรวจสอบข้อมูลนำเข้าและรายการที่อนุญาต
การตรวจสอบเป็นแนวป้องกันชั้นที่สองที่มีประโยชน์ ใช้รายการที่อนุญาต (ยอมรับเฉพาะรูปแบบที่ทราบว่าปลอดภัย) แทนรายการที่ปฏิเสธ (พยายามห้ามอักขระที่ไม่ดี)
ตัวอย่างเช่น ช่อง ID ที่เป็นตัวเลขควรปฏิเสธทุกสิ่งที่ไม่ใช่ตัวเลข ก่อนที่ข้อมูลจะไปถึงคำสั่งค้นหา
if not user_id.isdigit():
raise ValueError('invalid id')
# only then use the valueการหลีกอักขระเป็นทางเลือกสุดท้าย
การหลีกอักขระอัญประกาศด้วยตนเองมีความเปราะบางและเกิดข้อผิดพลาดได้ง่าย ฐานข้อมูลแต่ละชนิดมีกฎการหลีกอักขระต่างกัน และกรณีขอบ เช่น เทคนิคการเข้ารหัสข้อมูลและการฉีดคำสั่งแบบลำดับที่สอง อาจหลุดรอดไปได้
ควรใช้คำสั่งแบบกำหนดพารามิเตอร์ การหลีกอักขระควรใช้เฉพาะเมื่อระบบแมปวัตถุกับฐานข้อมูลหรือโปรแกรมควบคุมไม่สามารถกำหนดพารามิเตอร์ให้ตัวระบุบางรายการได้
สิทธิ์เท่าที่จำเป็นสำหรับบัญชีฐานข้อมูล
จำกัดความเสียหายจากการฉีดคำสั่งที่สำเร็จ โดยใช้สิทธิ์เท่าที่จำเป็นกับผู้ใช้ฐานข้อมูลของแอปพลิเคชัน
- ให้สิทธิ์เฉพาะ
SELECT,INSERT,UPDATEบนตารางที่จำเป็น - อย่าใช้บัญชีผู้ดูแลระบบสูงสุดหรือบัญชี
rootกับแอป - ปฏิเสธ
DROP,FILEและสิทธิ์ผู้ดูแลระบบ
GRANT SELECT, INSERT, UPDATE ON appdb.orders TO 'webapp'@'%';
REVOKE DROP, ALTER ON appdb.* FROM 'webapp'@'%';ระบบแมปวัตถุกับฐานข้อมูลและเครื่องมือสร้างคำสั่ง
ระบบแมปวัตถุกับฐานข้อมูลสมัยใหม่ (Hibernate, Sequelize, Django ORM, SQLAlchemy) จะกำหนดพารามิเตอร์ให้โดยปริยาย จึงลดความเสี่ยงจากการฉีดคำสั่งได้เกือบทั้งหมด
อันตรายจะกลับมาเมื่อผู้พัฒนาเปลี่ยนไปใช้ SQL โดยตรง หรือใช้การแทนค่าสตริงในเครื่องมือสร้างคำสั่ง ควรส่งค่าเป็นพารามิเตอร์ที่ผูกไว้เสมอ แม้จะอยู่ในโหมด SQL โดยตรง
การป้องกันหลายชั้น
ไม่มีการควบคุมใดเพียงอย่างเดียวที่เพียงพอ ควรใช้การป้องกันหลายชั้นร่วมกัน:
- คำสั่งแบบกำหนดพารามิเตอร์ทุกแห่ง (แนวป้องกันหลัก)
- การตรวจสอบข้อมูลนำเข้าและรายการที่อนุญาต
- บัญชีฐานข้อมูลที่มีสิทธิ์เท่าที่จำเป็น
- ไฟร์วอลล์แอปพลิเคชันเว็บ (WAF) เพื่อดักจับรูปแบบที่เป็นที่รู้จัก
- การจัดการข้อผิดพลาดที่ไม่เปิดเผยคำสั่ง SQL หรือร่องรอยสแต็ก
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจเกี่ยวกับแนวป้องกันหลัก
ทบทวน
คุณได้เรียนรู้ว่าการฉีดคำสั่ง SQL ทำงานอย่างไรและหยุดยั้งได้อย่างไร:
- การฉีดคำสั่ง SQL เกิดจากการนำข้อมูลนำเข้าที่ไม่น่าเชื่อถือต่อเข้ากับคำสั่งค้นหา
- คำสั่งแบบกำหนดพารามิเตอร์เป็นแนวป้องกันหลัก
- เพิ่มการตรวจสอบด้วยรายการที่อนุญาต บัญชีฐานข้อมูลที่มีสิทธิ์เท่าที่จำเป็น และ WAF
- หลีกเลี่ยงการหลีกอักขระด้วยตนเองและ SQL แบบไดนามิกภายในกระบวนงานที่จัดเก็บไว้
การป้องกันหลายชั้นช่วยไม่ให้ข้อผิดพลาดเพียงจุดเดียวกลายเป็นการละเมิดความปลอดภัย
คำถามที่พบบ่อย
บทเรียน “การป้องกัน SQL Injection” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การป้องกัน SQL Injection” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Cyber Security Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Cyber Security Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การป้องกัน SQL Injection”
ป้องกันการโจมตีแบบฉีดคำสั่ง คุณปฏิบัติ Cyber Security Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Cyber Security Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Cyber Security Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การป้องกัน SQL Injection” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Cyber Security Academy นี้ได้ไหม
ได้ บทเรียน Cyber Security Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การป้องกัน SQL Injection
- การควบคุมการเข้าถึงและการเข้ารหัส
- การตรวจสอบและการเฝ้าติดตาม
- ความปลอดภัยของการสำรองและกู้คืนข้อมูล