php - verificación - ¿Cómo proporciono más seguridad para verificar el origen de la solicitud?
procedimiento para verificar el origen de las mercancias (3)
Comprobar HTTP_REFERRER
para CSRF es una forma válida de protección. Aunque es trivial falsificar este encabezado HTTP en su OWN BROWSER, no es posible falsificarlo en el navegador de otra persona utilizando CSRF porque rompe las reglas .
De acuerdo con el Departamento de Seguridad Nacional, he encontrado la vulnerabilidad CSRF más peligrosa que se haya encontrado y se encuentra entre las 1,000 vulnerabilidades más peligrosas de todos los tiempos. Motorola corrigió esta falla usando un control de referencia, y es común ver este método de protección en el hardware de red integrado porque la memoria es escasa.
Un método más común y más seguro es almacenar un $_SESSION
cifrado dentro de una variable $_SESSION
y verificar esto para cada solicitud sensible. Un enfoque sencillo es usar POST
para todas las solicitudes confidenciales (como cambiar su contraseña) y asegúrese de que esta clave criptográfica sea válida para todas las publicaciones en un archivo de encabezado php, si no es válida y luego no unset($_POST);
. Este método funciona porque aunque un atacante puede forzar a su navegador a enviar solicitudes GET / POST, no puede ver la RESPUESTA, y no puede leer este token necesario para falsificar la solicitud. Este token se puede obtener con XSS, así que asegúrese de probar su sitio para xss .
Un buen método para generar un token csrf es md5(uniqid(mt_rand(),true));
Esto debería ser suficiente entropía para detener el CSRF. md5 () se utiliza para ocultar cómo se genera la sal. Tenga en cuenta que la hora actual no es un secreto, el atacante sabe exactamente a qué hora se produce la solicitud de CSRF y puede limitarse cuando se creó la sesión. Debe suponer que el atacante puede hacer muchas conjeturas, y en la práctica esto es simple de lograr escribiendo un montón de iframes en la página.
Estoy desarrollando una aplicación web PHP, quiero proporcionar más seguridad a la aplicación para que nadie pueda romper fácilmente la funcionalidad.
Breve explicación sobre mi problema: en un módulo hay una etapa en la que estoy verificando el origen de la solicitud (de donde viene esta solicitud)
Actualmente, estoy usando la variable HTTP_REFERRER
(disponible en php). Estoy comprobando este valor de variable con una URL específica (p. Ej., Http://www.example.com/test.php ). Si existe una coincidencia exacta, entonces solo estoy llamando a otras acciones.
Estoy un poco confundido con el enfoque anterior, si debo usar HTTP_REFERRER o verificar con la dirección IP (solicitud válida si proviene de una dirección IP específica)?
También quiero conocer mejores enfoques para brindar seguridad.
¿Alguien tiene idea, entonces por favor comparte?
Gracias por adelantado
Lección n. ° 1 en seguridad web: NUNCA confíes en la entrada del usuario. Y cuando digo nunca, quiero decir nunca. ;) Incluir el HTTP_REFER var en PHP que se ve comprometido fácilmente con un encabezado http (fuente: http://www.mustap.com/phpzone_post_62_how-to- bypass-the-referer-se)
Una posible solución para verificar la fuente es usar un token de formulario (protección csrf): http://www.thespanner.co.uk/2007/04/12/one-time-form-tokens/ pero no es tan seguro. cualquiera y solo es posible con tu propia fuente.
Un ejemplo simple de protección CSRF (falsificación de solicitudes entre sitios): (Por lo tanto, lo simple. Para obtener una solución más segura / sólida, consulte la respuesta de The Rook)
1) En su página de formulario, cree algún tipo de token y ponga su sesión y en un campo de formulario oculto:
<?php
session_start();
$csrfToken = md5(uniqid(mt_rand(),true)); // Token generation updated, as suggested by The Rook. Thanks!
$_SESSION[''csrfToken''] = $token;
?>
<form action="formHandler.php">
<input type="hidden" name="csrfKey" value="<?php echo $csrfToken ?>" />
</form>
2) En su controlador de formulario, compruebe si el token es válido.
<?php
session_start();
if($_POST[''csrfKey''] != $_SESSION[''csrfKey'']) {
die("Unauthorized source!");
}
?>
Treur lo hizo bien, pero aún quiero aclarar algunas cosas y proporcionarle algunas fuentes de material de referencia. Como dijo Treur, NUNCA confíes nunca en los datos de entrada del usuario, que incluyen todos los encabezados enviados por el navegador.
Lo que está describiendo es un típico ataque de falsificación de solicitudes entre sitios. Comprobar el encabezado de referencia no es una protección válida contra ataques CSRF, ya que de acuerdo con el RFC2616 ( Protocolo de transferencia de hipertexto 1.1 ), el encabezado del referer es opcional y, por lo tanto, puede ser omitido por el navegador en cualquier momento. Si está utilizando SSL, los buscadores siempre omiten el encabezado del referer. En segundo lugar, es un valor definido por el usuario, y por lo tanto no debe ser confiable.
La protección recomendada contra los ataques CSRF es usar el patrón de token sincronizado. Esto significa que debe crear un token secreto que está incrustado como un campo oculto en su formulario. Cuando se publica el formulario, verifica que el token secreto esté presente y que sea válido. Existen múltiples estrategias para crear tokens de seguridad. Describiré una forma de crear los tokens:
Para cada acción en su aplicación, cree un nombre de acción único para ellos. Por ejemplo, "delete_user", "add_user" o "save_user_profile". Digamos que el formulario que describió tiene el nombre de acción "foobar". Concatenar el nombre de la acción con la identificación de la sesión del usuario y un valor secreto.
$stringValue = "foobar" . "secret value" . session_id();
Para crear el token de seguridad, cree un hash de la cadena concatenada, puede usar sha1 para crear el hash. Para disminuir el riesgo de ataques de fuerza bruta, use una tecla más grande en el hash, por ejemplo, sha 512.
$secretToken = hash("sha5125", $stringValue);
Establezca este token en el campo oculto de su formulario. Cuando se envíe el formulario, vuelva a crear el token y verifique que coincida con el enviado en el formulario. Este token es válido para una sesión de usuario. Se puede argumentar que existe una ventana de oportunidad donde un atacante puede reutilizar el token ya que no se regenera en cada solicitud. Sin embargo, con estrategias adecuadas de gestión de sesiones, esto no debería ser realmente una preocupación.
Como dije, es necesaria una gestión adecuada de la sesión. Esto significa que no debe mantener las sesiones activas demasiado tiempo. Especialmente las vulnerabilidades de fijación de sesión deshacen cualquier medida de protección CSRF, ya que el atacante controla la sesión del usuario y, por lo tanto, puede "predecir" los tokens secretos.
Aquí hay un par de enlaces que le recomiendo que lea: