0Pricing
Cyber Security Academy · บทเรียน

การป้องกัน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การป้องกัน SQL Injection
  2. การควบคุมการเข้าถึงและการเข้ารหัส
  3. การตรวจสอบและการเฝ้าติดตาม
  4. ความปลอดภัยของการสำรองและกู้คืนข้อมูล
← กลับไปที่ Cyber Security Academy