SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์
ขจัดความเสี่ยงจากการแทรกคำสั่งด้วยการใช้คำสั่งที่เตรียมไว้ร่วมกับ PDO เสมอ
SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์ เป็นบทเรียน PHP Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน PHP Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน
SQL Injection คืออะไร
การแทรกคำสั่ง SQL เกิดขึ้นเมื่อฝังข้อมูลที่ผู้ใช้ส่งมาไว้ในคำค้นหา SQL โดยตรง ทำให้ผู้โจมตีสามารถบิดเบือนคำค้นหาเพื่อเข้าถึง แก้ไข หรือลบข้อมูลได้
ตัวอย่างแบบคลาสสิก
การต่อข้อมูลขาเข้าของผู้ใช้เข้ากับ SQL:
<?php
// VULNERABLE: attacker enters username = "' OR '1'='1"
$sql = "SELECT * FROM users WHERE username = '".$_GET["username"]."'";
// Becomes: SELECT * FROM users WHERE username = '' OR '1'='1'
// Returns ALL users!ตัวอย่างการลักลอบนำข้อมูลออก
ผู้โจมตีใช้ UNION SELECT เพื่อดึงข้อมูลจากตารางอื่นออกมา
// Input: ' UNION SELECT username, password FROM admin_users--
// This appends a second SELECT returning admin credentialsคำสั่งที่เตรียมไว้คือทางแก้
เมื่อใช้คำสั่งที่เตรียมไว้ โครงสร้างคำค้นหาจะถูกกำหนดไว้ก่อนที่จะส่งข้อมูลใด ๆ ฐานข้อมูลจะถือว่าค่าที่ผูกไว้ทั้งหมดเป็นข้อมูลตามตัวอักษร ไม่ใช่โค้ด SQL
<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$_GET["username"]]);
// Safe even if username = "' OR 1=1--"ตัวแทนตำแหน่งแบบมีชื่อ
ตัวแทนตำแหน่งแบบมีชื่อช่วยให้อ่านได้ชัดเจนขึ้น โดยเฉพาะเมื่อมีพารามิเตอร์หลายตัว
<?php
$stmt = $pdo->prepare(
"SELECT * FROM users WHERE email = :email AND active = :active"
);
$stmt->execute([":email" => $email, ":active" => true]);Eloquent ปลอดภัยโดยค่าเริ่มต้น
Laravel Eloquent ใช้คำสั่งที่เตรียมไว้ของ PDO ภายในสำหรับการดำเนินการมาตรฐานทั้งหมดของตัวสร้างคำค้นหา
<?php
// Safe:
User::where("email", $email)->first();
// UNSAFE: raw query with user input!
DB::select("SELECT * FROM users WHERE email = ".$email);คำค้นหาแบบดิบ
เมื่อจำเป็นต้องใช้ SQL แบบดิบใน Laravel ให้ใช้การผูกพารามิเตอร์ทุกครั้ง
<?php
// Safe raw query:
$users = DB::select("SELECT * FROM users WHERE email = ?", [$email]);
// Or with named bindings:
$users = DB::select("SELECT * FROM users WHERE email = :email", [":email" => $email]);การแทรกคำสั่งในส่วนคำสั่ง LIKE
ส่วนคำสั่ง LIKE ต้องจัดการเป็นพิเศษ อักขระไวลด์การ์ด (%, _) ต้องถูกหลีกด้วยตนเองก่อนการผูกค่า
<?php
$search = str_replace(["%", "_", "\\"], ["\%", "\_", "\\\\"], $userInput);
$stmt = $pdo->prepare("SELECT * FROM products WHERE name LIKE ?");
$stmt->execute(["%$search%"]);การแทรกคำสั่งใน ORDER BY
ไม่สามารถกำหนดชื่อคอลัมน์และทิศทางของ ORDER BY ด้วยพารามิเตอร์ได้ ให้ตรวจสอบค่าเทียบกับรายการที่อนุญาต
<?php
$allowedColumns = ["name", "price", "created_at"];
$col = in_array($request->sort, $allowedColumns) ? $request->sort : "name";
$dir = $request->dir === "desc" ? "desc" : "asc";
// Then safely build the query stringโพรซีเยอร์ที่จัดเก็บไว้
โพรซีเยอร์ที่จัดเก็บไว้ก็อาจมีช่องโหว่ได้ หากนำข้อมูลขาเข้ามาต่อกันภายในโพรซีเยอร์ ให้ใช้การเรียกแบบมีพารามิเตอร์ทุกครั้ง
หลักการให้สิทธิ์น้อยที่สุด
ผู้ใช้ฐานข้อมูลที่เชื่อมต่อจาก PHP ควรมีสิทธิ์ SELECT/INSERT/UPDATE/DELETE เฉพาะในตารางที่จำเป็นเท่านั้น ไม่ควรมีสิทธิ์ CREATE, DROP หรือสิทธิ์ผู้ดูแลระบบ
สรุป
ใช้คำสั่งที่เตรียมไว้พร้อมพารามิเตอร์ที่ผูกค่าไว้ ALWAYS ห้ามต่อข้อมูลขาเข้าของผู้ใช้เข้ากับ SQL โดยตรง ตรวจสอบ ORDER BY และชื่อคอลัมน์กับรายการที่อนุญาต และใช้ PDO โดยปิดการเตรียมคำสั่งจำลอง
ตรวจสอบความเข้าใจอย่างรวดเร็ว
วิธีที่ถูกต้องในการป้องกันการแทรกคำสั่ง SQL คืออะไร
คำถามที่พบบ่อย
บทเรียน “SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส PHP Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์”
ขจัดความเสี่ยงจากการแทรกคำสั่งด้วยการใช้คำสั่งที่เตรียมไว้ร่วมกับ PDO เสมอ คุณปฏิบัติ PHP Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน PHP Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน PHP Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน PHP Academy นี้ได้ไหม
ได้ บทเรียน PHP Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การป้องกัน Cross-Site Scripting (XSS)
- SQL Injection และคำสืบค้นแบบกำหนดพารามิเตอร์
- การป้องกัน CSRF
- การจัดเก็บรหัสผ่านอย่างปลอดภัย