Seguridad PHP: Protege tu sitio de SQL Injection y XSS

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Tu código PHP en la mira: por qué el silencio no es oro

\n\n

Imagina esto: lanzas tu sitio web, todo funciona a la perfección, tus clientes están contentos. Mientras tanto, en algún rincón oscuro de internet, un script kiddie escribe en tu formulario de búsqueda la mágica cadena ' OR 1=1 --. Y la base de datos, como un sirviente obediente, le entrega todas las contraseñas de los usuarios. ¿Te suena familiar? Lamentablemente, para muchos desarrolladores principiantes, sí.

\n\n

La seguridad en PHP no es una burocracia aburrida, es la protección real de tu tiempo, dinero y reputación. Hoy vamos a analizar a los dos principales enemigos de las aplicaciones web: las inyecciones SQL y el cross-site scripting (XSS). Aprenderás a identificarlos, neutralizarlos y nunca más permitirlos en tu código.

\n\n

Inyecciones SQL: cuando el usuario se convierte en hacker

\n\n

Una inyección SQL es un ataque en el que un atacante «inyecta» código SQL malicioso a través de campos de entrada. Si simplemente insertas los datos del usuario en una consulta, es como si le abrieras la puerta al ladrón tú mismo.

\n\n

Cómo se ve un código vulnerable

\n\n

Aquí tienes un ejemplo clásico que todavía se encuentra en libros antiguos y en sitios web reales:

\n\n
<?php\n// ¡PELIGROSO! Nunca hagas esto\n$username = $_POST['username'];\n$password = $_POST['password'];\n\n$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";\n$result = mysqli_query($conn, $query);\n?>
\n\n

¿Qué sucede si en el campo username escribes admin' --? La consulta se convierte en:

\n\n
SELECT * FROM users WHERE username = 'admin' --' AND password = ''
\n\n

El doble guión -- comenta el resto de la consulta. ¡Listo! El atacante ingresa como administrador sin contraseña. ¿Y si escribe '; DROP TABLE users; --? Adiós, usuarios.

\n\n

El salvavidas: Consultas preparadas (Prepared Statements)

\n\n

La mejor forma de protegerte contra las inyecciones SQL es usar consultas preparadas con PDO o MySQLi. Estas separan la lógica de la consulta de los datos, por lo que el código malicioso nunca se ejecutará.

\n\n

Así se ve un código seguro con PDO:

\n\n
<?php\n// ¡SEGURO! Usamos consultas preparadas\n$username = $_POST['username'];\n$password = $_POST['password'];\n\n$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password");\n$stmt->execute(['username' => $username, 'password' => $password]);\n$user = $stmt->fetch();\n?>
\n\n

Ahora, incluso si el atacante envía admin' OR 1=1 --, PDO lo tratará como una cadena de texto normal, no como parte de un comando SQL. La base de datos dirá: «Buscando un usuario con ese nombre tan extraño». Y no lo encontrará.

\n\n

¿Por qué PDO y no mysql_*?

\n\n
    \n
  • Seguridad por defecto: PDO escapa los datos automáticamente.
  • \n
  • Flexibilidad: soporta diferentes bases de datos (MySQL, PostgreSQL, SQLite).
  • \n
  • Placeholders con nombre: el código es más legible y fácil de mantener.
  • \n
  • Enfoque orientado a objetos: un estilo de programación moderno.
  • \n
\n\n

Las funciones mysql_* se eliminaron en PHP 7.0, y fue para bien. Si todavía usas mysqli_real_escape_string, es mejor que nada, pero PDO sigue siendo más fiable.

\n\n

Ataques XSS: cuando el código se esconde en los comentarios

\n\n

El cross-site scripting (XSS) es la inserción de código JavaScript en una página a través de la entrada del usuario. Imagina que un usuario deja un comentario, pero en lugar de texto escribe:

\n\n
<script>alert('¡Tu sitio ha sido hackeado!');</script>
\n\n

Si muestras esto sin procesar, cada visitante verá una ventana emergente. ¿Y si en lugar de alert hubiera un código que robe cookies o redirija a un sitio de phishing?

\n\n

Tipos de ataques XSS

\n\n
    \n
  • Reflejado (Reflected): el código malicioso

Blogs

Book Recommendations