mirror of
https://github.com/php/doc-es.git
synced 2026-03-24 15:32:36 +01:00
854 lines
36 KiB
XML
854 lines
36 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 55e0481a24fd4d7db21b62f1885973edbca25e60 Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
|
|
<chapter xml:id="session.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Sesiones y Seguridad</title>
|
|
<para>
|
|
Enlace externo: <link xlink:href="&url.session-fixation;">Fijación de sesión</link>
|
|
</para>
|
|
<para>
|
|
La gestión de las sesiones HTTP representa el núcleo de la seguridad en la web.
|
|
Medidas de mitigación <emphasis>deben</emphasis> ser consideradas para asegurar
|
|
la seguridad de las sesiones.
|
|
Los desarrolladores deben activar/utilizar los parámetros de seguridad apropiados.
|
|
</para>
|
|
|
|
<sect1 xml:id="features.session.security.management">
|
|
<title>Gestión básica de sesiones</title>
|
|
|
|
<sect2 xml:id="features.session.security.management.basic">
|
|
<title>Seguridad de sesiones</title>
|
|
<para>
|
|
El módulo de sesión no puede garantizar que la información almacenada
|
|
en una sesión sea vista únicamente por el usuario que
|
|
ha creado la sesión. Medidas adicionales son necesarias para
|
|
proteger la confidencialidad de la sesión, según el valor
|
|
que se le asigne.
|
|
</para>
|
|
|
|
<para>
|
|
La importancia de los datos almacenados en una sesión debe ser evaluada
|
|
y protecciones adicionales pueden ser desplegadas;
|
|
esto tiene obligatoriamente un costo como ser menos práctico para
|
|
el usuario. Por ejemplo, para proteger a los usuarios
|
|
de una táctica simple, la directiva <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
debe ser activada. En este caso, las cookies deben ser
|
|
activadas obligatoriamente lado-cliente sino las sesiones no
|
|
funcionarán.
|
|
</para>
|
|
|
|
<para>
|
|
Existen varias formas de divulgar identificadores de sesión a
|
|
terceros. Por ejemplo, inyecciones Javascript, identificadores
|
|
de sesión en las URLs, sniffing de paquetes, acceso físico
|
|
al dispositivo, etc.
|
|
Un identificador de sesión divulgado permite a un tercero acceder
|
|
a todos los recursos asociados con dicho identificador. Primero,
|
|
las URLs que contienen los identificadores de sesión. Si hay enlaces
|
|
a sitios o recursos externos, la URL que incluye el identificador
|
|
de sesión debe ser almacenada en los logs referrer del sitio externo.
|
|
Si estos datos no están cifrados, los identificadores de sesión
|
|
serán transmitidos en texto plano por la red. La solución aquí es
|
|
implementar SSL/TLS en el servidor y hacerlo obligatorio para los
|
|
usuarios. HSTS debe ser utilizado para mejorar también la
|
|
seguridad.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Incluso HTTPS no puede proteger la confidencialidad de los datos
|
|
en todos los casos. Por ejemplo, las vulnerabilidades CRIME y BEAST
|
|
permiten a un atacante leer los datos. Además, note
|
|
que algunas redes utilizan proxys HTTPS MITM para
|
|
auditorías. Los atacantes también pueden establecer este tipo de proxy.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.non-adaptive-session">
|
|
<title>Gestión de sesiones no adaptativas</title>
|
|
|
|
<para>
|
|
El gestor de sesiones de PHP es adaptativo, por defecto.
|
|
Un gestor de sesiones adaptativo introduce
|
|
riesgos adicionales.
|
|
</para>
|
|
|
|
<para>
|
|
Cuando <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
está activado, y el gestor de guardado de sesiones lo soporta,
|
|
un identificador de sesión no inicializado es rechazado, y uno nuevo es creado.
|
|
Esto previene un ataque que fuerza a los usuarios a utilizar un
|
|
identificador de sesión conocido.
|
|
Un atacante puede pasar enlaces o enviar emails que contienen
|
|
el identificador de sesión.
|
|
Por ejemplo: <literal>http://example.com/page.php?PHPSESSID=123456789</literal> si
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link> está activado,
|
|
la víctima iniciará una sesión utilizando el identificador de sesión
|
|
proporcionado por el atacante.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
permite anular este tipo de riesgo.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Los gestores de guardado definidos por el usuario también pueden
|
|
soportar el modo de sesión estricto implementando
|
|
la validación de identificadores de sesión. Todos los gestores de
|
|
guardado definidos por el usuario deben implementar la validación
|
|
de identificadores de sesión.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
La cookie de identificador de sesión puede ser definida con los
|
|
atributos domain, path, httponly, secure y, desde PHP 7.3, SameSite.
|
|
Existe una prioridad definida por los navegadores.
|
|
Utilizando las prioridades, un atacante puede definir el identificador de
|
|
sesión que puede ser utilizado permanentemente. El uso de la
|
|
directiva <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
no permite resolver este problema.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
permite mitigar este riesgo. Con la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On,
|
|
el identificador de sesión no inicializado será rechazado.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Aunque la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
limita los riesgos concernientes al gestor adaptativo de sesión, un
|
|
atacante puede forzar a los usuarios a utilizar un identificador de
|
|
sesión no inicializado que ha sido creado por el atacante, por ejemplo, mediante inyecciones
|
|
Javascript. Este tipo de ataque puede ser limitado utilizando las
|
|
recomendaciones de este manual.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Siguiendo este manual, los desarrolladores deben activar la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>,
|
|
utilizar timestamps basados en el gestor de sesión,
|
|
y regenerar los identificadores de sesión utilizando la función
|
|
<function>session_regenerate_id</function> con los procedimientos
|
|
recomendados. Si los desarrolladores siguen estas instrucciones, un identificador de sesión
|
|
generado por un atacante será normalmente eliminado.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Cuando ocurre un acceso a una sesión obsoleta, los desarrolladores
|
|
deben guardar todas las datos de la sesión activa del
|
|
usuario; estas informaciones serán útiles para futuras
|
|
investigaciones. El usuario debe ser forzado a desconectarse
|
|
de todas las sesiones, por ejemplo, forzándolo a identificarse de
|
|
nuevo. Esto permite contrarrestar ataques utilizando sesiones robadas.
|
|
</simpara>
|
|
</note>
|
|
|
|
<warning>
|
|
<simpara>
|
|
El acceso a una sesión obsoleta no significa necesariamente que se trate de una
|
|
ataque. Una red inestable y/o la eliminación inmediata de la sesión
|
|
activa hará que usuarios legítimos utilicen sesiones obsoletas.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Desde 7.1.0, la función <function>session_create_id</function> ha sido
|
|
añadida. Esta función permite acceder a todas las sesiones activas
|
|
de un usuario prefijando los identificadores de sesión con el identificador
|
|
del usuario. La activación de la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
es vital en esta configuración. De lo contrario, los usuarios maliciosos
|
|
pueden definir identificadores de sesiones para otros usuarios.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Los usuarios de versiones anteriores a PHP 7.1.0 <emphasis>deben</emphasis>
|
|
utilizar <acronym>CSPRNG</acronym>, por ejemplo, <filename>/dev/urandom</filename>, o la función
|
|
<function>random_bytes</function> y las funciones de hash
|
|
para generar un nuevo identificador de sesión. La función
|
|
<function>session_create_id</function> posee mecanismos de detección
|
|
de colisiones, y genera un identificador de sesión siguiendo las
|
|
configuraciones INI de las sesiones. El uso de la función
|
|
<function>session_create_id</function> es recomendado.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-id-regeneration">
|
|
<title>Regeneración de un identificador de sesión</title>
|
|
|
|
<para>
|
|
La directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
es un buen compromiso pero no es suficiente. Los desarrolladores deben
|
|
también utilizar la función <function>session_regenerate_id</function>
|
|
para la seguridad de las sesiones.
|
|
</para>
|
|
|
|
<para>
|
|
La regeneración de un identificador de sesión reduce el riesgo de robo de identificadores
|
|
de sesión, por lo que la función <function>session_regenerate_id</function>
|
|
debe ser utilizada periódicamente; por ejemplo, regenerar el identificador de sesión cada
|
|
15 minutos para asegurar contenido sensible. Incluso en el caso de que
|
|
un identificador de sesión sea robado, tanto el usuario legítimo
|
|
como el atacante tendrán su sesión que expirará. En otras palabras, el acceso
|
|
al contenido por el usuario o el atacante generará un error de acceso
|
|
a una sesión obsoleta.
|
|
</para>
|
|
|
|
<para>
|
|
Los identificadores de sesión <emphasis>deben</emphasis> ser regenerados cuando
|
|
los privilegios del usuario son elevados, como después de una autenticación.
|
|
La función <function>session_regenerate_id</function> debe ser llamada
|
|
antes de almacenar las informaciones de autenticación en <varname>$_SESSION</varname>.
|
|
(la función <function>session_regenerate_id</function>
|
|
guarda los datos de sesión actuales automáticamente para
|
|
guardar timestamps/etc... en la sesión actual.)
|
|
Asegúrese de que la nueva sesión contenga la bandera de autenticación.
|
|
</para>
|
|
|
|
<para>
|
|
Los desarrolladores <emphasis>no deben</emphasis> basarse en
|
|
la expiración del identificador de sesión definida por la directiva
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>.
|
|
Los atacantes pueden acceder al identificador de sesión de la víctima
|
|
de forma periódica para evitar su expiración, y permitir su explotación
|
|
incluyendo con sesiones autenticadas.
|
|
</para>
|
|
|
|
<para>
|
|
En su lugar, los desarrolladores deben implementar un timestamp
|
|
basado en la gestión de datos de sesión.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Aunque el gestor de sesión puede manejar los timestamps de forma
|
|
transparente, esta funcionalidad no está implementada. Los datos
|
|
de las sesiones antiguas deben ser conservados hasta que el recuperador
|
|
de memoria no haya pasado. Simultáneamente, los desarrolladores deben asegurarse
|
|
ellos mismos de que los datos de sesión obsoleta sean efectivamente borrados.
|
|
Sin embargo, los desarrolladores no deben borrar los datos
|
|
de sesión activa demasiado rápido. Por ejemplo, <code>session_regenerate_id(true);</code>
|
|
y <function>session_destroy</function> nunca deben ser llamados
|
|
al mismo tiempo para una sesión activa. Esto puede parecer contradictorio,
|
|
pero es un requisito del mandante.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
<function>session_regenerate_id</function> <emphasis>no borrará</emphasis>
|
|
las sesiones antiguas por defecto. Las sesiones autenticadas obsoletas
|
|
pueden estar presentes para ser utilizadas. Los desarrolladores deben asegurarse
|
|
de que las sesiones antiguas no sean utilizadas por nadie.
|
|
Deben prohibir el acceso a los datos de sesión obsoleta
|
|
utilizando ellos mismos timestamps.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
La eliminación repentina de una sesión activa produce efectos secundarios
|
|
indeseables. Las sesiones pueden desaparecer cuando hay conexiones
|
|
concurrentes en la aplicación web y/o cuando la red es inestable.
|
|
</simpara>
|
|
<simpara>
|
|
Los accesos potencialmente maliciosos son indetectables con la eliminación
|
|
repentina de una sesión.
|
|
</simpara>
|
|
<simpara>
|
|
En lugar de eliminar las sesiones obsoletas inmediatamente, los desarrolladores
|
|
deben definir un corto tiempo de expiración (timestamp) en
|
|
<varname>$_SESSION</varname>, y prohibir el acceso a los datos de sesión.
|
|
</simpara>
|
|
<simpara>
|
|
Los desarrolladores no deben prohibir el acceso a los datos de las
|
|
sesiones antiguas inmediatamente después de la ejecución de la función
|
|
<function>session_regenerate_id</function>. El acceso debe ser prohibido
|
|
en una etapa posterior; por ejemplo, unos segundos después para redes
|
|
estables, como una red cableada y unos minutos después para redes
|
|
inestables como teléfonos móviles o redes Wi-Fi.
|
|
</simpara>
|
|
<simpara>
|
|
Si un usuario accede a una sesión obsoleta (sesión expirada), el acceso
|
|
a esta sesión debe ser rechazado. También es recomendado borrar el
|
|
estado de autenticación de todas las sesiones de usuario, ya que esto
|
|
puede representar un eje de ataque.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
El uso de la directiva <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link> y de la función
|
|
<function>session_regenerate_id</function> pueden causar un DoS personal
|
|
con cookies no eliminadas definidas por los atacantes. En este caso,
|
|
los desarrolladores pueden invitar a los usuarios a eliminar las cookies
|
|
y advertirles que pueden encontrar un problema de seguridad.
|
|
Los atacantes pueden definir cookies maliciosas mediante una aplicación
|
|
web vulnerable, un plugin de navegador expuesto o viciado, un dispositivo
|
|
físico comprometido, etc...
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
No se confunda sobre el riesgo DoS. <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
es obligatorio para la seguridad de los identificadores de sesión !
|
|
Todos los sitios son animados a activar la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
|
|
</simpara>
|
|
<simpara>
|
|
DoS solo puede ocurrir cuando la cuenta sufre un ataque. Una inyección
|
|
Javascript en una aplicación representa la mayoría de los ejes de ataque.
|
|
</simpara>
|
|
</warning>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-data-deletion">
|
|
<title>Eliminación de datos de sesión</title>
|
|
|
|
<para>
|
|
Los datos de sesiones obsoletas deben ser inaccesibles
|
|
y deben ser eliminados. El módulo actual de sesión
|
|
no soporta este aspecto.
|
|
</para>
|
|
|
|
<para>
|
|
Los datos de sesiones obsoletas deben ser eliminados tan pronto
|
|
como sea posible. Sin embargo, las sesiones activas no deben ser
|
|
eliminadas instantáneamente. Para satisfacer estas recomendaciones, los desarrolladores
|
|
mismos deben implementar un gestor de datos de sesión basado en
|
|
timestamp.
|
|
</para>
|
|
|
|
<para>
|
|
Defina y gestione la expiración del timestamp en la variable
|
|
global $_SESSION. Prohíba el acceso a los datos de sesiones
|
|
caducadas. Cuando se detecte un acceso a datos de sesión obsoleta,
|
|
debe eliminarse todo el estado autenticado de las sesiones
|
|
de usuario y forzar a los usuarios a autenticarse de nuevo.
|
|
El acceso a datos de sesiones obsoletas puede representar un ataque.
|
|
Para lograr esto, los desarrolladores deben seguir todas las sesiones
|
|
activas de todos los usuarios.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
El acceso a una sesión obsoleta también puede ocurrir debido a una red inestable
|
|
y/o un acceso concurrente a un sitio web, por ejemplo, el servidor intenta definir un
|
|
nuevo identificador de sesión mediante una cookie, pero el paquete Set-Cookie nunca
|
|
llegó al cliente debido a una pérdida de conexión. Una conexión puede
|
|
crear un nuevo identificador de sesión mediante la función <function>session_regenerate_id</function>,
|
|
pero otra conexión concurrente puede no haber recibido
|
|
aún el identificador de sesión. Sin embargo, los desarrolladores deben prohibir el acceso
|
|
a una sesión obsoleta en un momento más lejano. Por ejemplo, la gestión de sesiones
|
|
basada en timestamp es obligatoria.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
En resumen, los datos de sesiones no deben ser destruidos con la función
|
|
<function>session_regenerate_id</function>, ni con la función <function>session_destroy</function>,
|
|
pero los timestamps deben ser utilizados para controlar el acceso a los datos de
|
|
sesión. Deje que la función <function>session_gc</function> elimine los datos obsoletos
|
|
desde el almacenamiento de datos de sesiones.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-locking">
|
|
<title>Sesión y Bloqueo</title>
|
|
|
|
<para>
|
|
Los datos de sesión están bloqueados por defecto para evitar los
|
|
accesos concurrentes. El bloqueo es obligatorio para mantener una
|
|
consistencia de los datos de sesión a través de las peticiones.
|
|
</para>
|
|
|
|
<para>
|
|
Sin embargo, el bloqueo de sesión puede ser utilizado por los atacantes
|
|
para realizar ataques DoS. Para minimizar el riesgo de un ataque DoS
|
|
por bloqueo de sesión, debe minimizarse el uso de bloqueos.
|
|
Utilice datos en modo solo lectura cuando los datos de sesión
|
|
no necesiten ser actualizados. Utilice la opción 'read_and_close'
|
|
con la función <function>session_start</function>.
|
|
<code>session_start(['read_and_close'=>1]);</code> cerrará
|
|
la sesión tan pronto como sea posible después de actualizar la variable
|
|
global $_SESSION utilizando la función <function>session_commit</function>.
|
|
</para>
|
|
|
|
<para>
|
|
El módulo de sesión actual <emphasis>no detecta</emphasis>
|
|
todas las modificaciones de la variable $_SESSION cuando
|
|
la sesión está inactiva. Es responsabilidad del desarrollador
|
|
no modificar la variable $_SESSION cuando la sesión está inactiva.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.active-sessions">
|
|
<title>Sesiones activas</title>
|
|
|
|
<para>
|
|
Los desarrolladores deben mantener un registro de todas las sesiones
|
|
activas de cada usuario, y notificarles el número de sesiones
|
|
activas, desde qué dirección IP, desde cuándo, etc.
|
|
PHP no mantiene registros de estas informaciones. Los desarrolladores
|
|
están supuestos a hacerlo ellos mismos.
|
|
</para>
|
|
|
|
<para>
|
|
Existen diferentes formas de hacerlo. Una implementación posible
|
|
es definir una base de datos que mantenga un registro de los datos
|
|
necesarios, y almacenar todas las informaciones pertinentes.
|
|
Dado que los datos de sesión son GCed, los desarrolladores deben
|
|
tener cuidado con los datos GCed para mantener la base de datos
|
|
de sesiones activas consistente.
|
|
</para>
|
|
|
|
<para>
|
|
Una de las implementaciones simples es "el identificador de usuario prefijando
|
|
el identificador de sesión" y almacenar las informaciones necesarias en
|
|
la variable $_SESSION. La mayoría de las bases de datos son relativamente
|
|
eficientes para seleccionar un prefijo en forma de &string;.
|
|
Los desarrolladores DEBEN utilizar la función <function>session_regenerate_id</function>
|
|
así como la función <function>session_create_id</function> para esto.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Nunca utilice datos confidenciales como prefijo.
|
|
Si el identificador de usuario es confidencial, debería utilizar
|
|
la función <function>hash_hmac</function>.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<warning>
|
|
<simpara>
|
|
La activación de la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
es obligatoria para este tipo de configuración. Asegúrese de que
|
|
esté activada. De lo contrario, la base de datos de sesiones activas
|
|
puede ser comprometida.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
El gestor de sesión basado en timestamp es obligatorio
|
|
para detectar el acceso a sesiones obsoletas. Cuando se detecte el acceso a una
|
|
sesión obsoleta, la bandera de autenticación debe ser eliminada de todas las sesiones activas del usuario.
|
|
Esto permite evitar que los atacantes continúen explotando las sesiones
|
|
robadas.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-and-autologin">
|
|
<title>Sesión y auto-identificación</title>
|
|
|
|
<para>
|
|
Los desarrolladores no deben utilizar identificadores de sesión con una
|
|
larga duración para la auto-identificación, ya que esto aumenta el riesgo
|
|
de utilizar sesiones robadas. Una funcionalidad de auto-identificación
|
|
debe ser implementada por el desarrollador.
|
|
</para>
|
|
|
|
<para>
|
|
Utilice una clave de hash segura de un solo uso como clave
|
|
de auto-identificación utilizando la función
|
|
<function>setcookie</function>. Utilice un hash seguro
|
|
más fuerte que SHA-2. Por ejemplo, SHA-256 o superior con datos
|
|
aleatorios desde la función <function>random_bytes</function>
|
|
o mediante <filename>/dev/urandom</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Si el usuario no está autenticado, verifique si la clave de auto-identificación
|
|
de un solo uso es válida o no. En el caso de que sea válida, autentifique
|
|
al usuario y defina una nueva clave de hash segura de un solo uso.
|
|
Una clave de auto-identificación solo debe ser utilizada una vez, por ejemplo, nunca utilice
|
|
una clave de auto-identificación, y siempre regénela.
|
|
</para>
|
|
|
|
<para>
|
|
Una clave de auto-identificación es una clave de autenticación con una
|
|
larga duración, debe ser protegida tanto como sea posible.
|
|
Utilice los atributos de cookie path/httponly/secure/SameSite para protegerla.
|
|
Por ejemplo, nunca transmita la clave de auto-identificación a menos que sea necesario.
|
|
</para>
|
|
|
|
<para>
|
|
Los desarrolladores deben implementar las funcionalidades que
|
|
desactivan la auto-identificación, y eliminan las cookies
|
|
que contienen las claves de auto-identificación no necesarias.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.csrf">
|
|
<title>Attaques CSRF (Cross-Site Request Forgeries)</title>
|
|
|
|
<para>
|
|
Las sesiones y las autenticaciones no protegen contra los
|
|
ataques CSRF. Los desarrolladores deben implementar protecciones
|
|
CSRF ellos mismos.
|
|
</para>
|
|
|
|
<para>
|
|
La función <function>output_add_rewrite_var</function> puede ser utilizada para
|
|
la protección CSRF. Consulte las páginas del manual para más detalles.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
PHP, antes de su versión 7.2.0, utiliza el mismo buffer de salida y las
|
|
mismas configuraciones INI que la configuración trans-sid. Sin embargo, el uso
|
|
de la función <function>output_add_rewrite_var</function> con versiones
|
|
de PHP anteriores a 7.2.0 no es recomendado.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
La mayoría de los frameworks de aplicaciones web soportan
|
|
la protección CSRF. Consulte el manual de su
|
|
framework de aplicación web para más detalles.
|
|
</para>
|
|
|
|
<para>
|
|
Desde PHP 7.3, el atributo SameSite de la cookie de sesión puede ser definido.
|
|
Esto es una medida adicional que puede minimizar
|
|
las vulnerabilidades CSRF.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
<sect1 xml:id="session.security.ini">
|
|
<title>Seguridad de las configuraciones INI de sesión</title>
|
|
|
|
<para>
|
|
Al asegurar las configuraciones INI de sesiones, los desarrolladores
|
|
pueden experimentar la seguridad de las sesiones. Muchas configuraciones
|
|
INI no tienen una configuración recomendada. Los desarrolladores son
|
|
responsables de la correcta configuración de las sesiones.
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-lifetime">session.cookie_lifetime</link>=0
|
|
</para>
|
|
<para>
|
|
El valor <literal>0</literal> tiene un significado importante.
|
|
Informa a los navegadores de no almacenar la cookie en un
|
|
espacio de almacenamiento permanente. También, cuando el navegador se cierra,
|
|
la cookie de identificación de sesión es eliminada inmediatamente.
|
|
Si los desarrolladores definen un valor diferente de 0, permite
|
|
a otros usuarios utilizar el identificador de sesión. La
|
|
mayoría de las aplicaciones deben utilizar "<literal>0</literal>" como
|
|
valor.
|
|
</para>
|
|
<para>
|
|
Si se desea una funcionalidad de auto-identificación, los desarrolladores
|
|
deben implementar su propio sistema de auto-identificación seguro.
|
|
No utilice identificadores de sesión de larga duración para esto.
|
|
Para más información, consulte la sección adecuada de esta documentación.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-cookies">session.use_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
Aunque las cookies HTTP sufren de problemas técnicos, siguen siendo
|
|
la forma preferida de gestionar los identificadores de sesiones.
|
|
Utilice solo cookies para la gestión de identificadores de sesiones
|
|
cuando sea posible. La mayoría de las aplicaciones deben utilizar
|
|
una cookie para el identificador de sesión.
|
|
</para>
|
|
<para>
|
|
Si <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=Off,
|
|
el módulo de sesión utilizará los valores del identificador
|
|
de sesión definidos por las variables GET o POST proporcionadas,
|
|
y la cookie del identificador de sesión no será inicializada.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
</para>
|
|
<para>
|
|
Aunque la activación de <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
es obligatoria para la seguridad de las sesiones, esta directiva está
|
|
desactivada por defecto.
|
|
</para>
|
|
<para>
|
|
Este modo evita que el módulo de sesión utilice un identificador de sesión
|
|
no inicializado. Dicho de otra forma, el módulo de sesión solo va a aceptar
|
|
identificadores de sesiones válidos generados por el módulo de sesión.
|
|
Rechazará todos los identificadores de sesión proporcionados por los usuarios.
|
|
</para>
|
|
<para>
|
|
Debido a la especificación de cookies, los atacantes son capaces
|
|
de colocar cookies que contienen identificadores de sesiones configurando
|
|
localmente una base de datos de cookies o mediante inyecciones Javascript.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> puede evitar que un atacante
|
|
inicialice un identificador de sesión.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Los atacantes pueden inicializar un identificador de sesión con su
|
|
propio dispositivo, y pueden definir el identificador de sesión
|
|
de su víctima. Deben entonces mantener el identificador de sesión
|
|
activo para poder abusar de él.
|
|
Los atacantes deben pasar por muchos otros pasos para tener éxito en su ataque
|
|
en este escenario. También, el uso de la directiva
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> permite limitar los riesgos.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-httponly">session.cookie_httponly</link>=On
|
|
</para>
|
|
<para>
|
|
Permite rechazar el acceso a una cookie de sesión desde javascript.
|
|
Esta configuración evita que una cookie sea corrompida por una
|
|
inyección Javascript.
|
|
</para>
|
|
<para>
|
|
Es posible utilizar un identificador de sesión como token CSRF, pero
|
|
no es recomendado. Por ejemplo, fuentes HTML pueden ser
|
|
guardadas y enviadas a otros usuarios.
|
|
Los desarrolladores no deben escribir los identificadores de sesión en las
|
|
páginas web por razones de seguridad. Todas las aplicaciones web deben
|
|
utilizar el atributo httponly para la cookie que contiene el identificador de sesión.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
El token CSRF debe ser renovado periódicamente, al igual que el identificador
|
|
de sesión.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-secure">session.cookie_secure</link>=On
|
|
</para>
|
|
<para>
|
|
Permite acceder a la cookie de identificador de sesión únicamente cuando
|
|
el protocolo es HTTPS. Si un sitio web solo es accesible por HTTPS,
|
|
esta directiva debe ser activada.
|
|
</para>
|
|
<para>
|
|
HSTS debe ser utilizado para los sitios web accesibles solo por HTTPS.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Lax" o
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Strict"
|
|
</para>
|
|
<para>
|
|
Desde PHP 7.3, el atributo <literal>"SameSite"</literal> puede ser definido
|
|
para la cookie de identificador de sesión. Este atributo es una forma de
|
|
mitigar los ataques CSRF (Cross Site Request Forgery).
|
|
</para>
|
|
<para>
|
|
La diferencia entre Lax y Strict es la accesibilidad de la cookie en las peticiones
|
|
originadas de otros dominios empleando el método HTTP GET.
|
|
Las cookies utilizando Lax serán accesibles mediante una petición GET originada
|
|
de otro dominio, mientras que las cookies utilizando Strict no lo serán.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>=[elija el más pequeño posible]
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link> es una configuración para eliminar
|
|
el identificador de sesión obsoleto. Confiar
|
|
completamente en esta configuración <emphasis>no es</emphasis> recomendado.
|
|
Los desarrolladores deben gestionar la duración de las sesiones con un timestamp
|
|
por ellos mismos.
|
|
</para>
|
|
<para>
|
|
La GC de sesiones (recolección de basura) es mejor realizada utilizando
|
|
la función <function>session_gc</function>.
|
|
La función <function>session_gc</function> debe ser ejecutada por un gestor
|
|
de tareas; por ejemplo, un cron en los sistemas Unix.
|
|
</para>
|
|
<para>
|
|
GC es ejecutado por probabilidad, por defecto. Esta configuración
|
|
<emphasis>no garantiza</emphasis> que las sesiones antiguas sean
|
|
eliminadas. Aunque los desarrolladores no deben basarse en este parámetro,
|
|
se recomienda definirlo con el valor más pequeño posible.
|
|
Debe ajustarse las directivas <link
|
|
linkend="ini.session.gc-probability">session.gc_probability</link>
|
|
y <link
|
|
linkend="ini.session.gc-divisor">session.gc_divisor</link> de modo que
|
|
las sesiones obsoletas sean eliminadas con la frecuencia apropiada.
|
|
Si la funcionalidad de auto-identificación es necesaria, los desarrolladores
|
|
deben implementar su propia funcionalidad de auto-identificación segura;
|
|
consulte a continuación para más información. Nunca utilice el identificador
|
|
de sesión de larga duración para realizar este tipo de funcionalidad.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Algunos módulos de gestión de guardado de sesiones no utilizan esta
|
|
funcionalidad basada en expiración y probabilidad; por ejemplo,
|
|
memcached, memcache. Consulte la documentación de estos gestores
|
|
de guardado de sesiones para más detalles.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>=Off
|
|
</para>
|
|
<para>
|
|
El uso de un gestor de identificadores de sesiones transparente
|
|
no está prohibido. Los desarrolladores deben emplearlo cuando sea necesario.
|
|
Sin embargo, la desactivación de la gestión de identificadores de sesión de
|
|
forma transparente permite asegurar un poco más los identificadores de sesión
|
|
eliminando la posibilidad de una inyección de identificador de sesión o
|
|
fuga de este identificador.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
El identificador de sesión puede filtrarse desde URLs guardadas,
|
|
URLs en emails, una fuente HTML guardada, etc...
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-tags">session.trans_sid_tags</link>=[banderas limitadas]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Los desarrolladores no deben reescribir banderas HTML
|
|
innecesarias. El valor por defecto debe ser suficiente para
|
|
la mayoría de los usos. Para versiones de PHP más antiguas,
|
|
utilice en su lugar
|
|
<link linkend="ini.url-rewriter.tags">url_rewriter.tags</link>.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-hosts">session.trans_sid_hosts</link>=[hosts limitados]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Este parámetro define una lista blanca de hosts que están
|
|
autorizados a reescribir los identificadores de sesión transparentes. ¡Nunca
|
|
añada hosts que no sean de confianza!
|
|
El módulo de sesión solo autoriza <literal>$_SERVER['HTTP_HOST']</literal>
|
|
cuando este parámetro está vacío.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.referer-check">session.referer_check</link>=[URL de origen]
|
|
</para>
|
|
<para>
|
|
Cuando el parámetro <link
|
|
linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
|
|
está activo.
|
|
Este parámetro reduce los riesgos de inyección de identificador de sesión.
|
|
Si un sitio web es <literal>http://example.com/</literal>,
|
|
defina como valor para este parámetro <literal>http://example.com/</literal>.
|
|
Tenga en cuenta que los navegadores HTTPS no envían el encabezado referrer.
|
|
Los navegadores pueden no enviar el encabezado referrer debido
|
|
a su propia configuración. Por lo tanto, este parámetro no puede ser
|
|
considerado como una medida fiable de seguridad.
|
|
A pesar de todo, su uso es recomendado.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cache-limiter">session.cache_limiter</link>=nocache
|
|
</para>
|
|
<para>
|
|
Asegura que el contenido HTTP no sea almacenado en caché para las sesiones
|
|
autenticadas. Permite el almacenamiento en caché solo para los contenidos
|
|
que no son privados. De lo contrario, el contenido será expuesto.
|
|
El valor <literal>"private"</literal> debe ser empleado si el contenido HTTP no incluye
|
|
datos sensibles desde un punto de vista de seguridad. Tenga en cuenta que <literal>"private"</literal>
|
|
puede transmitir datos privados almacenados en caché para los clientes
|
|
compartidos. <literal>"public"</literal> solo debe ser utilizado cuando el contenido HTML
|
|
no contiene ningún dato privado.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.hash-function">session.hash_function</link>="sha256"
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 <) Una función de hash fuerte generará un identificador
|
|
de sesión fuerte. Aunque una colisión de hash es poco probable con algoritmos
|
|
de hash MD5, los desarrolladores deben utilizar SHA-2 o un
|
|
algoritmo de hash más fuerte como sha384 y sha512.
|
|
Los desarrolladores deben asegurarse de una longitud suficiente de
|
|
la <link linkend="ini.session.entropy-length">entropía</link> para la
|
|
función de hash utilizada.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.save-path">session.save_path</link>=[directorio no legible por todos]
|
|
</para>
|
|
<para>
|
|
Si este parámetro está definido a un directorio accesible en lectura por todos,
|
|
como <filename>/tmp</filename> (por defecto), otros usuarios del servidor
|
|
serán capaces de recuperar las sesiones listando los archivos presentes
|
|
en este directorio.
|
|
</para>
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|