Vulnerabilidades de seguridad de PHP: secuestro de sesiones, secuencias de comandos entre sitios, inyección de SQL y cómo solucionarlas

Seguridad en PHP

Al escribir código PHP, es muy importante tener en cuenta las siguientes vulnerabilidades de seguridad para evitar escribir código inseguro.

Tipos de vulnerabilidades

Estas son las vulnerabilidades comunes que encontrará al escribir código PHP. Discutiremos algunos en mayor profundidad a continuación.

  • Falsificación de solicitudes entre sitios Una vulnerabilidad en la aplicación causada por el programador que no verifica desde dónde se envió una solicitud: este ataque se envía a un usuario de alto nivel de privilegios para obtener acceso de mayor nivel a la aplicación.
  • Cross Site Scripting Una vulnerabilidad en la aplicación causada por el programador que no desinfecta la entrada antes de enviarla al navegador (por ejemplo, un comentario en un blog). Se usa comúnmente para ejecutar javascript malicioso en el navegador para realizar ataques como el robo de cookies de sesión entre otras acciones maliciosas para obtener privilegios de mayor nivel en la aplicación.
  • Inclusión de archivos locales Una vulnerabilidad en la aplicación causada por el programador que requiere una entrada de archivo proporcionada por el usuario y no desinfecta la entrada antes de acceder al archivo solicitado. Esto da como resultado que se incluya un archivo donde no debería haber estado.
  • Inclusión de archivos remotos Una vulnerabilidad en la aplicación causada por el programador que requiere una entrada de archivo proporcionada por el usuario y no desinfecta la entrada antes de acceder al archivo solicitado. Esto da como resultado que un archivo se extraiga de un servidor remoto y se incluya donde no debería estar.
  • Secuestro de sesión Una vulnerabilidad causada por un atacante que obtiene acceso al identificador de sesión de un usuario y puede usar la cuenta de otro usuario haciéndose pasar por él. Suele utilizarse para acceder a la cuenta de un usuario administrativo.
  • Adquisición del identificador de sesión La adquisición del identificador de sesión es una vulnerabilidad causada por un atacante que puede adivinar el identificador de sesión de un usuario o explotar vulnerabilidades en la aplicación misma o en el navegador del usuario para obtener un identificador de sesión.
  • Inyección SQL Una vulnerabilidad en la aplicación causada por el programador que no desinfecta la entrada antes de incluirla en una consulta en la base de datos. Esto hace que el atacante tenga acceso completo de lectura y, la mayoría de las veces, de escritura a la base de datos. Con este tipo de acceso, un atacante puede hacer cosas muy malas.

Ahora veamos algunas vulnerabilidades comunes con más detalle.

Secuestro de sesión

El secuestro de sesión es una vulnerabilidad causada por un atacante que obtiene acceso al identificador de sesión de un usuario y puede usar la cuenta de otro usuario haciéndose pasar por él. Suele utilizarse para acceder a la cuenta de un usuario administrativo.

Defensa contra ataques de secuestro de sesión en PHP

Para defenderse de los ataques de secuestro de sesión, debe verificar la información del navegador y la ubicación del usuario actual con la información almacenada sobre la sesión. A continuación se muestra una implementación de ejemplo que puede ayudar a mitigar los efectos de un ataque de secuestro de sesión. Verifica la dirección IP, el agente de usuario y si la sesión expiró, eliminando una sesión antes de que se reanude.

 ($_SESSION['lastaccess'] + 3600)) { session_unset(); session_destroy(); } else { $_SESSION['lastaccess'] = time(); }

Secuencias de comandos entre sitios

Cross Site Scripting es un tipo de vulnerabilidad en una aplicación web causada porque el programador no desinfecta la entrada antes de enviarla al navegador web (por ejemplo, un comentario en un blog). Se usa comúnmente para ejecutar javascript malicioso en el navegador web para realizar ataques como el robo de cookies de sesión, entre otras acciones maliciosas, para obtener privilegios de nivel superior en la aplicación web.

Ejemplo de ataque de secuencia de comandos entre sitios

Un blog permite a los usuarios diseñar sus comentarios con etiquetas HTML, sin embargo, el script que alimenta el blog no elimina las etiquetas, lo que permite que cualquier usuario ejecute javascript en la página. Un atacante puede usar esto en su beneficio para ejecutar javascript malicioso en el navegador. Podrían infectar a los usuarios con malware, robar cookies de sesión y más.

 alert('Cross Site Scripting!'); 

Defender su sitio web de ataques de secuencias de comandos entre sitios en PHP

En PHP hay dos funciones principales htmlspecialchars()y strip_tags(), integradas para protegerse de los ataques de secuencias de comandos entre sitios.

La htmlspecialchars($string)función evitará que una cadena HTML se represente como HTML y la mostrará como texto sin formato en el navegador web. Ejemplo de código htmlspecialchars ()


    

The other approach is the strip_tags($string, $allowedtags) function which removes all HTML tags except for the HTML tags that you’ve whitelisted. It’s important to note that with the strip_tags() function you have to be more careful, this function does not prevent the user from including javascript as a link, you’ll have to sanitize that on our own.

strip_tags() code example


     

"; echo strip_tags($usercomment, $allowedtags);

Configuración del encabezado de protección X-XSS:

En PHP puede enviar el X-XSS-Protectionencabezado que le indicará a los navegadores que busquen un ataque de Cross Site Scripting reflejado y bloqueen la carga de la página. Esto no evita todos los ataques de secuencias de comandos entre sitios, solo los reflejados y deben usarse en combinación con otros métodos.


    

Writing your own sanitization function Another option, if you would like more control over how the sanitization works, is to write your own HTML Sanitization function, this is not recommended for PHP Beginners as a mistake would make your website vulnerable.

Defending your website from cross site scripting attacks with a Content Security Policy

An effective approach to preventing cross site scripting attacks, which may require a lot of adjustments to your web application’s design and code base, is to use a content security policy.

Set a Content Security Policy as an HTTP Header

The most common way of setting a Content Security Policy is by setting it directly in the HTTP Header. This can be done by the web server by editing it’s configuration or by sending it through PHP.

Example of a Content Security Policy set in a HTTP Header


     

Set a Content Security Policy as a Meta tags

You can include your Content Security Policy in the page’s HTML and set on a page by page basis. This method requires you to set on every page or you lose the benefit of the policy.

Example of a Content Security Policy set in a HTML Meta Tag


      SQL Injection

SQL injection is a vulnerability in the application caused by the programmer not sanitizing input before including it into a query into the database. This leads to the attacker having full read and more often than not write access to the database. With this type of access an attacker can do very bad things.

Example SQL Injection attack

The below PHP Script runs an SQL Statement to get a user’s email by ID. However the input is not sanitized making it vulnerable to SQL Injection

connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT email FROM users WHERE idemail"]; } } else { echo "no results"; } $conn->close();
SELECT email FROM users WHERE id = `$input`;

So with the above the input is not type casted (I.e. casting the input with (int) so only a number is allowed) nor escaped allowing someone to perform an SQL Injection attack - for example the URL getemailbyuserid.php?id=1'; My Query Here-- - would allow you to run arbitrary SQL queries with little effort.

Defending your website from sql injection attacks in PHP

There are a few approaches to defend your website from SQL Injection Attacks. These approaches are Whitelisting, Type Casting, and Character Escaping

Whitelisting: The whitelisting approach is used in cases where only a few inputs are expected. You can list each expected input in a PHP Switch and then have a default for invalid input. You do not have to worry about a type casting issue or a character escape bypass but the allowed input is extreamly limited. It remains an option, see the example below.


        

Type Casting: The type casting approach is commonly used for an application using numeric input. Simply cast the input with (int) $input and only a numeric value will be allowed.

Character Escaping: The character escaping approach will escape characters such as quotes and slashes provided by the user to prevent an attack. If you are using MySQL Server and the MySQLi library to access your database, the mysqli_real_escape_string($conn, $string) function will take two arguments, the MySQLi connection, and the string and will properly escape the user’s input to block an sql injection attack. The exact function you use depends on the database type and php library you are using check the php library’s documentation for more information on escaping user input.

More on PHP:

  • PHP best practices
  • Best PHP code examples
  • How to prevent a slow loris attack on a PHP server
  • How to set up a local debugging environment in PHP