Challenge 3 — Solution Task: Review this code and list every security issue you can find, then write a corrected version: session_start(); $name = $_POST['name']; echo "
"; $stmt = $pdo->query("SELECT * FROM users WHERE name = '$name'"); // Security issues found in the original code: // // 1. No safe-default read: $_POST['name'] is read directly with no ?? // fallback, triggering an undefined-key warning if the form hasn't // been submitted yet (Fundamentals Chapter 8's own guidance). // // 2. Reflected XSS: $name is echoed directly into the value='$name' // HTML attribute with no htmlspecialchars() escaping at all - a // value like "> would break out of // the attribute and execute as real JavaScript in the visitor's own // browser (Intermediate Chapter 8). // // 3. SQL injection: $name is concatenated directly into the SQL query // string rather than using a prepared statement with a placeholder // - a value like "' OR '1'='1" would return every row in the users // table instead of matching a specific name (Intermediate Chapter // 4's own exact warning example). // // 4. $pdo->query() is used instead of $pdo->prepare()/execute() - // query() has no mechanism for safely binding parameters at all, // so it should never be used with any value derived from user // input. "; $stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name"); $stmt->execute(['name' => $name]); $users = $stmt->fetchAll(); ?> Notes: - The corrected version fixes all four issues independently - each one needed its own specific defence, exactly matching this chapter's own "CSRF, XSS, and SQL injection are three SEPARATE vulnerabilities" quick-reference point (SQL injection and XSS here, specifically). - htmlspecialchars($name) is applied at the exact point of output (inside the value='...' attribute), not when $name was first read - matching the "escape on output, not on input" rule from Intermediate Chapter 8. - The SQL query now uses a named placeholder (:name) with execute() passing the real value separately - the database treats it strictly as data, never as part of the SQL command's own structure, exactly eliminating the injection risk the original code had. - This exercise deliberately combined an XSS bug and a SQL injection bug in the same small snippet, since real vulnerable code often has more than one problem in the same few lines - reviewing thoroughly rather than stopping at the first issue found matters in practice.