Implementar seguridad al programar con PHP (1)

Buenas prácticas de programación en PHP

Si estás empezando a desarrollar sistemas o páginas web con PHP, o si ya tienes algo de conocimiento previo con este lenguaje de programación, no me dejarás mentir con lo siguiente. Muchos aprendemos a programar con PHP a través de cursos, tutoriales, quizá algún libro especializado o incluso por nuestra propia cuenta a través de la página oficial, pero en este comienzo nadie nos enseña buenas prácticas para desarrollar con PHP (1) a implementar seguridad al programar con PHP (1), y cuando nos enseñan, casi nunca hay una explicación de por medio.

Aquí tienes una breve explicación de algunas buenas prácticas para empezar a programar con PHP cómo implementar seguridad al programar con PHP (1).

Uso de funciones seguras

PHP tiene muchas funciones que pueden ser inseguras si se usan de manera incorrecta. Por ejemplo, la función eval() puede ejecutar código malicioso. En su lugar, utiliza funciones seguras como htmlspecialchars() para escapar caracteres especiales en la salida HTML y evitar inyecciones de código.

<?php
// Evitar inyección de código
$usuario = htmlspecialchars($_POST['usuario']);
$password = htmlspecialchars($_POST['password']);
?>

La función eval() se utiliza para ejecutar una cadena de código PHP como si fuera una parte del código fuente original. Esto significa que el código dentro de la cadena se ejecutará y se procesará como si hubiera sido escrito directamente en el script de PHP. Es importante tener en cuenta que el uso de eval() puede ser peligroso, ya que puede permitir la ejecución de código malicioso si se utiliza de manera incorrecta.

Por otro lado, htmlspecialchars() se utiliza para convertir ciertos caracteres especiales en sus equivalentes de entidad HTML. Esta función es útil para evitar la ejecución no deseada de código o la inyección de código en sitios web que permiten la entrada de usuarios. htmlspecialchars() convierte los caracteres como <, >, &, ", ', en sus entidades HTML correspondientes para que el navegador los muestre correctamente en la página web.

Validación de entrada

No confíes en la entrada del usuario. Valida siempre la información antes de procesarla o almacenarla en una base de datos. La validación debe incluir comprobaciones de tipo, longitud, formato y contenido. Además, utiliza siempre sentencias preparadas o parámetros vinculados para evitar inyecciones SQL.

<?php
// Validación de entrada
$nombre = $_POST['nombre'];
if (!preg_match("/^[a-zA-Z ]*$/",$nombre)) {
  echo "Solo se permiten letras y espacios en el nombre";
} else {
  // Almacenar en la base de datos
  $stmt = $pdo->prepare("INSERT INTO usuarios (nombre, email) VALUES (:nombre, :email)");
  $stmt->bindParam(':nombre', $nombre);
  $stmt->bindParam(':email', $email);
  $stmt->execute();
}
?>

Asegúrate de que todos los datos de entrada sean validados y sanitizados correctamente antes de ser utilizados. Esto incluye datos de formularios, parámetros de URL, cookies, cabeceras HTTP y cualquier otro dato proporcionado por el usuario. Utiliza funciones específicas para cada tipo de datos y evita la validación manual.

<?php
// Validación de datos de entrada
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
  echo "La dirección de correo electrónico no es válida";
  exit();
}
?>

Autenticación y autorización

Asegúrate de que los usuarios solo puedan acceder a las áreas del sitio que tienen permitido. Utiliza contraseñas seguras y no las almacenes en texto plano. Además, utiliza técnicas de autenticación robustas como OAuth2 en lugar de autenticación básica.

<?php
// Autenticación y autorización
session_start();
if (!isset($_SESSION['usuario'])) {
  header('Location: login.php');
  exit();
} else {
  if ($_SESSION['nivel'] !== 'administrador') {
    echo "No tiene permisos para acceder a esta página";
    exit();
  }
}
?>

Control de acceso y privilegios

Asegúrate de que los usuarios solo tengan acceso a las partes del sitio que necesitan. Limita los privilegios de los usuarios a lo que necesitan para realizar sus tareas. Además, utiliza técnicas como el principio de privilegio mínimo para limitar el daño en caso de que un usuario sea comprometido.

<?php
// Control de acceso y privilegios
if ($_SESSION['nivel'] !== 'administrador') {
  echo "No tiene permisos para acceder a esta página";
  exit();
}
?>

Manejo de errores y excepciones

Asegúrate de que tu código maneje correctamente los errores y las excepciones. No reveles información sensible en los mensajes de error. En su lugar, muestra un mensaje genérico y registra los detalles del error en un archivo de registro.

<?php
// Manejo de errores y excepciones
try {
  // Código que puede lanzar una excepción
} catch (Exception $e) {
  error_log($e->getMessage());
  echo "Ha ocurrido un error inesperado. Por favor, inténtelo de nuevo más tarde.";
}
?>

Protección contra ataques de fuerza bruta

Para evitar que los atacantes puedan descubrir contraseñas a través de ataques de fuerza bruta, debes limitar el número de intentos de inicio de sesión y utilizar técnicas de captcha o similares para evitar que los bots automatizados puedan intentar iniciar sesión en el sitio.

<?php
// Protección contra ataques de fuerza bruta
session_start();
if (isset($_SESSION['intentos'])) {
  $_SESSION['intentos']++;
} else {
  $_SESSION['intentos'] = 1;
}
if ($_SESSION['intentos'] > 3) {
  echo "Demasiados intentos de inicio de sesión. Inténtelo de nuevo más tarde.";
  exit();
}
?>

Protección contra ataques CSRF

Asegúrate de que todas las acciones que modifican datos (como enviar formularios o hacer clic en enlaces) estén protegidas contra ataques CSRF. Utiliza tokens CSRF únicos y aleatorios para cada acción y valida que el token enviado por el usuario sea el mismo que el generado por el servidor.

<?php
// Protección contra ataques CSRF
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
  echo "Token CSRF no válido";
  exit();
}
?>

Conoce más sobre la Protección contra ataques CSRF en: CSRF: Si eres desarrollador web debes conocer cómo implementar esta protección

Por otro lado, recuerda mantener tu software y tus dependencias actualizadas con las últimas versiones y parches de seguridad.

  • Utiliza herramientas de gestión de dependencias como Composer, para asegurarte de que no estás utilizando versiones obsoletas y vulnerables.
  • Realiza pruebas de seguridad regulares en tus aplicaciones para detectar y corregir posibles vulnerabilidades.
  • Investiga sobre las herramientas de análisis estático y dinámico de código para detectar posibles problemas e implementalo.
  • También es recomendable realizar pruebas de penetración para simular ataques y evaluar la resistencia de tu aplicación.

Con estas buenas prácticas esta implementación de seguridad en tu programación con PHP, tendrás un buen comienzo y estarás en el buen camino para crear aplicaciones PHP seguras.

Si quieres saber la diferencia entre las Buenas Prácticas y la Implementación de Seguridad en programación con PHP, revisa el siguiente artículo.

Buenas practicas e implementación de seguridad en programación

Deja un comentario