1000-ft view: Injection occurs when untrusted input reaches an interpreter (SQL, HTML, etc.). This page shows secure patterns—parameterized queries, strict validation, and output encoding—across five scenarios: Login bypass, UNION search, Blind/Time-based probing, Second-order SQLi, and Stored XSS.
Uses the shared DB (same DSN) with module-scoped tables a03_*. Seed data lives in db/seed.sql.
Compare with the Insecure version.
Secure idea: never concatenate credentials into SQL.
Fetch by email with a prepared statement; verify with password_verify().
db/seed.sql).
Secure idea: use name LIKE ? with a bound value (%q%).
Return a fixed schema and suppress raw SQL errors.
Secure idea: coerce IDs to integers and bind them. Avoid dynamic concatenation and timing oracles.
? = :id and returns a safe count.Secure idea: validate/normalize on input; always use prepared statements when reusing stored fields.
Secure idea: store text as-is if you need auditability, but
always encode on output (e.g., htmlspecialchars). For rich text, use a strict allowlist/sanitizer.
Below, everything runs in SAFE mode (encoded output).