¿Cómo funcionan las cookies HttpOnly con las solicitudes AJAX?

195

JavaScript necesita acceso a las cookies si AJAX se usa en un sitio con restricciones de acceso basadas en cookies. ¿Funcionarán las cookies HttpOnly en un sitio AJAX?

Editar: Microsoft creó una forma de prevenir ataques XSS al deshabilitar el acceso de JavaScript a las cookies si se especifica HttpOnly. Firefox más tarde adoptó esto. Entonces mi pregunta es: si está utilizando AJAX en un sitio, como StackOverflow, ¿son una opción las cookies Http-Only?

Edición 2: Pregunta 2. Si el propósito de HttpOnly es evitar el acceso de JavaScript a las cookies, y aún puede recuperar las cookies a través de JavaScript a través del objeto XmlHttpRequest, ¿cuál es el objetivo de HttpOnly ?

Edición 3: Aquí hay una cita de Wikipedia:

Cuando el navegador recibe dicha cookie, se supone que debe usarla como de costumbre en los siguientes intercambios HTTP, pero no hacerla visible para los scripts del lado del cliente. [32] El HttpOnlyindicador no forma parte de ningún estándar y no se implementa en todos los navegadores. Tenga en cuenta que actualmente no hay prevención de leer o escribir la cookie de sesión a través de una solicitud XMLHTTP. [33]

Entiendo que document.cookiese bloquea cuando usas HttpOnly. Pero parece que aún puede leer los valores de las cookies en el objeto XMLHttpRequest, lo que permite XSS. ¿Cómo te hace HttpOnly más seguro que? ¿Al hacer cookies esencialmente solo de lectura?

En su ejemplo, no puedo escribirle document.cookie, pero aún puedo robarle su cookie y publicarla en mi dominio usando el objeto XMLHttpRequest.

<script type="text/javascript">
    var req = null;
    try { req = new XMLHttpRequest(); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
    if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
    req.open('GET', 'http://stackoverflow.com/', false);
    req.send(null);
    alert(req.getAllResponseHeaders());
</script>

Edición 4: lo siento, quise decir que podía enviar XMLHttpRequest al dominio StackOverflow y luego guardar el resultado de getAllResponseHeaders () en una cadena, eliminar la cookie y luego publicarlo en un dominio externo. Parece que Wikipedia y ha.ckers están de acuerdo conmigo en esto, pero me encantaría ser reeducado ...

Edición final: Ahh, aparentemente ambos sitios están equivocados, esto es realmente un error en Firefox . IE6 y 7 son en realidad los únicos navegadores que actualmente son totalmente compatibles con HttpOnly.

Para reiterar todo lo que he aprendido:

  • HttpOnly restringe todo el acceso a document.cookie en IE7 y FireFox (no estoy seguro acerca de otros navegadores)
  • HttpOnly elimina la información de cookies de los encabezados de respuesta en XMLHttpObject.getAllResponseHeaders () en IE7.
  • Los XMLHttpObjects solo se pueden enviar al dominio del que se originaron, por lo que no hay publicación de dominio cruzado de las cookies.

editar: es probable que esta información ya no esté actualizada.

Shawn
fuente
Lancé su ejemplo en un script greasemonkey y parece que FF ya no muestra cookies. Excelente investigación y ejemplo.
Tal vez con la Política del mismo origen no pueda realizar una solicitud http a un dominio que no sea el mismo en el que se ejecuta el script; sin embargo, creo que podría pasar fácilmente las cookies redirigiendo al usuario a una página usando window.location y pasar toda la información a través de parámetros de cadena de consulta.
Luca Marzi
@LucaMarzi " no puede realizar una solicitud http a un dominio que no es el mismo en el que se ejecuta el script " ¿Está diciendo que un sitio X no puede incluir una imagen del host Y? (¿una característica que ha sido compatible con todos los navegadores desde Mosaic?)
curioso el

Respuestas:

64

Sí, las cookies HTTP-Only estarían bien para esta funcionalidad. Todavía se les proporcionará la solicitud XmlHttpRequest al servidor.

En el caso de Stack Overflow, las cookies se proporcionan automáticamente como parte de la solicitud XmlHttpRequest. No conozco los detalles de implementación del proveedor de autenticación de desbordamiento de pila, pero es probable que los datos de las cookies se usen automáticamente para verificar su identidad a un nivel inferior que el método del controlador de "voto".

En términos más generales, no se requieren cookies para AJAX. La compatibilidad con XmlHttpRequest (o incluso la comunicación remota de iframe, en navegadores más antiguos) es todo lo que se requiere técnicamente.

Sin embargo, si desea proporcionar seguridad para la funcionalidad habilitada para AJAX, se aplican las mismas reglas que con los sitios tradicionales. Necesita algún método para identificar al usuario detrás de cada solicitud, y las cookies son casi siempre el medio para ese fin.

En su ejemplo, no puedo escribir en su document.cookie, pero aún puedo robar su cookie y publicarla en mi dominio utilizando el objeto XMLHttpRequest.

XmlHttpRequest no realizará solicitudes de dominio cruzado (por exactamente el tipo de razones por las que está hablando).

Normalmente, puede inyectar un script para enviar la cookie a su dominio utilizando la comunicación remota iframe o JSONP, pero luego HTTP-Only protege la cookie nuevamente ya que es inaccesible.

A menos que haya comprometido StackOverflow.com en el lado del servidor, no podrá robar mi cookie.

Edición 2: Pregunta 2. Si el propósito de Http-Only es evitar el acceso de JavaScript a las cookies, y aún puede recuperar las cookies a través de JavaScript a través del objeto XmlHttpRequest, ¿cuál es el objetivo de Http-Only?

Considere este escenario:

  • Encuentro una vía para inyectar código JavaScript en la página.
  • Jeff carga la página y mi JavaScript malicioso modifica su cookie para que coincida con la mía.
  • Jeff envía una respuesta estelar a su pregunta.
  • Debido a que lo envía con mis datos de cookies en lugar de los suyos, la respuesta será mía.
  • Usted vota "mi" respuesta estelar.
  • Mi cuenta real entiende el punto.

Con las cookies HTTP-Only, el segundo paso sería imposible, por lo tanto, anularía mi intento de XSS.

Edición 4: lo siento, quería decir que podía enviar XMLHttpRequest al dominio StackOverflow y luego guardar el resultado de getAllResponseHeaders () en una cadena, eliminar la cookie y luego publicarlo en un dominio externo. Parece que Wikipedia y ha.ckers están de acuerdo conmigo en esto, pero me encantaría ser reeducado ...

Eso es correcto. Todavía puede sesión secuestrar de esa manera. Sin embargo, reduce significativamente el rebaño de personas que pueden ejecutar con éxito incluso ese hack de XSS en su contra.

Sin embargo, si usted va de nuevo a mi escenario de ejemplo, se puede ver donde sólo HTTP no cortar con éxito de los ataques XSS que se basan en la modificación de las cookies del cliente (no es raro).

Todo se reduce al hecho de que a) no solo mejora va a resolver todas las vulnerabilidades y b) ningún sistema será cada vez sea completamente segura. HTTP-Only es una herramienta útil para apuntalar contra XSS.

Del mismo modo, a pesar de que la restricción de dominio cruzado en XmlHttpRequest no es 100% exitosa en la prevención de todas las vulnerabilidades XSS, nunca soñaría con eliminar la restricción.

Dave Ward
fuente
Muchos marcos ponen csrf tokens en las cookies . Supongo que la llamada AJAX que necesita una csrfcomprobación no funcionará a menos que coloque el token csrf en un elemento HTML oculto para que JS lo recupere.
usuario
4

No necesariamente, depende de lo que quieras hacer. Podrías elaborar un poco? AJAX no necesita acceso a las cookies para funcionar, puede realizar solicitudes por su cuenta para extraer información, la solicitud de página que realiza la llamada de AJAX podría acceder a los datos de la cookie y transferirlos al script de llamada sin que Javascript tenga que acceder directamente a galletas

Glenn Slaven
fuente
4

Sí, son una opción viable para un sitio basado en Ajax. Las cookies de autenticación no son para la manipulación por secuencias de comandos, sino que simplemente las incluye el navegador en todas las solicitudes HTTP realizadas al servidor.

Los scripts no necesitan preocuparse por lo que dice la cookie de sesión: siempre que esté autenticado, cualquier solicitud al servidor iniciada por un usuario o el script incluirá las cookies apropiadas. El hecho de que los scripts no puedan conocer el contenido de las cookies no importa.

Para las cookies que se utilizan para fines distintos de la autenticación, estas se pueden configurar sin el indicador HTTP solamente, si desea que el script pueda modificarlas o leerlas. Puede elegir qué cookies deberían ser solo HTTP, por lo que, por ejemplo, cualquier cosa que no sea sensible, como las preferencias de la interfaz de usuario (orden de clasificación, contraer el panel izquierdo o no) se puede compartir en las cookies con los scripts.

Realmente me gustan las cookies HTTP solamente: es una de esas extensiones de navegador patentadas que fue una idea genial.

thomasrutter
fuente
3

Hay un poco más de esto.

Ajax no requiere estrictamente cookies, pero pueden ser útiles como otros carteles han mencionado. Marcar una cookie HTTPOnly para ocultarla de los scripts solo funciona parcialmente, porque no todos los navegadores lo admiten, sino también porque existen soluciones alternativas comunes.

Es extraño que los encabezados de respuesta XMLHTTP estén dando la cookie, técnicamente el servidor no tiene que devolver la cookie con la respuesta. Una vez que está configurado en el cliente, permanece configurado hasta que caduque. Aunque hay esquemas en los que la cookie se cambia con cada solicitud para evitar su reutilización. Por lo tanto, puede evitar esa solución cambiando el servidor para que no proporcione la cookie en las respuestas XMLHTTP.

Sin embargo, en general, creo que HTTPOnly debería usarse con cierta precaución. Hay ataques de secuencias de comandos en sitios cruzados en los que un atacante hace arreglos para que un usuario envíe una solicitud similar a ajax originada en otro sitio, utilizando formularios de publicación simples, sin el uso de XMLHTTP, y la cookie aún activa de su navegador autenticará la solicitud.

Si desea estar seguro de que una solicitud AJAX está autenticada, la solicitud en sí Y los encabezados HTTP deben contener la cookie. Por ejemplo, mediante el uso de scripts o entradas ocultas únicas. HTTPOnly dificultaría eso.

Por lo general, la razón interesante para querer HTTPOnly es evitar que el contenido de terceros incluido en su página web robe cookies. Pero hay muchas razones interesantes para ser muy cauteloso al incluir contenido de terceros y filtrarlo agresivamente.

davenpcj
fuente
1

El navegador maneja las cookies automáticamente cuando realiza una llamada AJAX, por lo que no es necesario que su Javascript se confunda con las cookies.

pkchukiss
fuente
1

Por lo tanto, supongo que JavaScript necesita acceso a sus cookies.

Todas las solicitudes HTTP de su navegador transmiten su información de cookies para el sitio en cuestión. JavaScript puede establecer y leer cookies. Las cookies no son, por definición, necesarias para las aplicaciones Ajax, pero son necesarias para la mayoría de las aplicaciones web para mantener el estado del usuario.

La respuesta formal a su pregunta está redactada: "¿JavaScript necesita acceso a las cookies si se utiliza AJAX?" - es por lo tanto "no". Piense en los campos de búsqueda mejorados que utilizan solicitudes de Ajax para proporcionar opciones de sugerencia automática, por ejemplo. No hay necesidad de información de cookies en ese caso.

Polsonby
fuente
XmlHttpRequest necesita cookies. La búsqueda mejorada que menciona puede estar detrás de una página de inicio de sesión. Pero si JavaScript necesita o no poder exponer el valor de la cookie a la VM es una pregunta diferente.
Mr. Shiny and New 安 宇
1

Como aclaración, desde la perspectiva del servidor, la página solicitada por una solicitud de AJAX no es esencialmente diferente de una solicitud de obtención de HTTP estándar realizada por el usuario que hace clic en un enlace. Todas las propiedades de solicitud normales: usuario-agente, ip, sesión, cookies, etc. se pasan al servidor.

Glenn Slaven
fuente
La "sesión" no es un concepto HTTP. Es un concepto de alto nivel construido sobre los conceptos HTTP por un marco.
curioso
0

No, la página que solicita la llamada AJAX también tiene acceso a cookies y eso es lo que comprueba si ha iniciado sesión.

Puede hacer otra autenticación con Javascript, pero no confiaría en él, siempre prefiero poner cualquier tipo de verificación de autenticación en el back-end.

Glenn Slaven
fuente
0

Sí, las cookies son muy útiles para Ajax.

Poner la autenticación en la URL de solicitud es una mala práctica. Hubo una noticia la semana pasada sobre cómo obtener los tokens de autenticación en las URL del caché de Google.

No, no hay forma de prevenir ataques. Los navegadores más antiguos aún permiten un acceso trivial a las cookies a través de JavaScript. Puede omitir solo http, etc. Cualquier cosa que se le ocurra puede obtenerse con el suficiente esfuerzo. El truco es hacer demasiado esfuerzo para que valga la pena.

Si desea que su sitio sea más seguro (no hay seguridad perfecta), puede usar una cookie de autenticación que caduque. Luego, si se roba la cookie, el atacante debe usarla antes de que caduque. Si no lo hacen, entonces tiene una buena indicación de que hay actividad sospechosa en esa cuenta. Cuanto más corto sea el intervalo de tiempo, mejor para la seguridad, pero más carga pone en su servidor para generar y mantener claves.

Arrendajo
fuente