AUTENTIFICACIÓN HTTP Emilio Casbas. 18/1/2006 INTRODUCCIÓN. 1. Autentificación digest 2. Autentificación básica 2.1Ejemplo práctico. 3. Autentificación proxy 3.1Ejemplo práctico 4. Conclusiones INTRODUCCIÓN. El protocolo HTTP 1.X tiene un mecanismo nativo de autentificación desafío/respuesta para pedir un usuario/password válido y acceder a recursos web. Este mecanismo se conoce como la autenticación HTTP y puede ser iniciado tanto por un script de CGI como el mismo servidor WEB. El principal propósito de este documento, es dar al usuario una definición y sentido común para comprender la autentificación HTTP al nivel de cabecera, ver en que entornos se utiliza, con que fines, y la problemática asociada. HTTP define dos protocolos de autentficación oficiales: autentificación básica y autentificación digest. Aquí, me centraré especialmente en el método de autentificación básica, que es el más ampliamente utilizado por clientes y servidores web, y el menos seguro. 1. AUTENTIFICACIÓN DIGEST La finalidad de la autentificación digest, es no enviar nunca el password a través de la red” para ello envía al servidor un “resumen” o “huella” de el password de una manera irreversible. La autentificación digest, fue desarrollada de forma compatible y como una alternativa más segura a la autentificación básica, pero no es uno de los protocolos denominados seguros comparados con aquellos que utilizan mecanismos de clave-pública (SSL) o mecanismos de intercambio de tickets (kerberos). La autentificación digest no posee una fuerte autentificación ni ofrece protección de confidencialidad fuera de la protección del password, el resto de la petición y respuesta van en texto plano. 2. AUTENTIFICACIÓN BÁSICA. La autentificación básica es uno de los protocolos de autentificación HTTP más utilizados. La mayoría de los clientes y servidores web la implementan. A continuación se exponen los pasos que componen este método de autentificación: 1. Un usuario solicita un recurso web (por ejemplo un index.html) 2. El servidor web comprueba que es un recurso protegido y le envía al cliente un desafío de password con la cabecera HTTP “Authorization Required” y código 401. 3. El navegador del usuario recibe el código y la cabecera de authorización y muestra el diálogo de usuario/contraseña. Cuando el usuario introduce los datos, el navegador realiza una codificación en base64 con los datos introducidos y lo reenvía al servidor en la cabecera del cliente “Authorization”. 4. El servidor decodifica el nombre de usuario y password, y comprueba que tiene acceso al recurso protegido. Como se puede comprobar, la autentificación básica transmite el par usuario:password de forma no encriptada desde el navegador al servidor y como tal, no debería ser usado para logins sensibles a menos que se este operando sobre un medio encriptado tal como SSL. 2.1 EJEMPLO PRÁCTICO. Paquetes capturados con ethereal en una conexión solicitando un recurso protegido en un servidor web. 1. El cliente envía una petición HTTP estándar solicitando un recurso. GET /cti/pruebas/ecasbas/ HTTP/1.1\r\n Host: www.prueba.es\r\n User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Accept: text/xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.1\r\n Accept-Language: en-us,en;q=0.7,es;q=0.3\r\n Accept-Encoding: gzip,deflate\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n Keep-Alive: 300\r\n Connection: keep-alive\r\n 2. El servidor web lee su archivo de configuración y determina que el recurso solicitado esta protegido con contraseña. El servidor sólo puede permitir el acceso a usuarios conocidos. 3. El servidor web entonces le contesta al cliente con una respuesta requerida de autorización indicándole al cliente el código HTTP 401. HTTP/1.0 401 Unauthorized\r\n Date: Mon, 16 Jan 2006 11:17:51 GMT\r\n Server: Apache/2.0.55 (Unix) mod_ssl/2.0.55 OpenSSL/0.9.7g PHP/5.1.1\r\n WWW-Authenticate: Basic realm="ByPassword"\r\n Accept-Ranges: bytes\r\n Content-Length: 3174\r\n Content-Type: text/html\r\n X-Cache: MISS from www.prueba.es\r\n Connection: keep-alive\r\n 4. El navegador del cliente, interpreta este código HTTP 401 como un desafío de autentificación, y el navegador entonces muestra el prompt de usuario:password mostrando el nombre del host y el realm. 5.El cliente reenvía la petición con el usuario/password introducidos en el prompt anterior. GET /cti/pruebas/ecasbas/ HTTP/1.1\r\n Host: www.unav.es\r\n User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Accept: text/tml+xml,text/html,image/jpeg,image/gif;q=0.2,*/*;q=0.1\r\n Accept-Language: en-us,en;q=0.7,es;q=0.3\r\n Accept-Encoding: gzip,deflate\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n Keep-Alive: 300\r\n Connection: keep-alive\r\n Authorization: Basic ZWNhc2JhczpwcnVlYmE=\r\n 6.El servidor compara la información del cliente con su lista de usuarios/passwords. Si la autorización falla, el servidor volverá a mandarle la cabecera de autentificación requerida HTTP 401. Si los datos introducios son correctos, el servidor mostrará el recurso solicitado. 7.El servidor da paso al recurso solicitado. HTTP/1.0 200 OK\r\n Date: Mon, 16 Jan 2006 11:17:58 GMT\r\n Server: Apache/2.0.55 (Unix) mod_ssl/2.0.55 OpenSSL/0.9.7g PHP/5.1.1\r\n Last-Modified: Fri, 13 Jan 2006 10:31:02 GMT\r\n ETag: "125b019-5-f636a580"\r\n Accept-Ranges: bytes\r\n Content-Length: 5\r\n Content-Type: text/html\r\n X-Cache: MISS from www.prueba.es\r\n Connection: keep-alive\r\n En los campos anteriores, hemos visto campos especiales que han sido añadidos a varias cabeceras HTTP. En el paso 3, cuando el servidor envía la respuesta con la cabecera 401, incluye un campo especial. WWW-Authenticate: Basic realm="ByPassword"\r\n El valor “Basic” muestra que estamos pidiendo al browser usar autentificación básica. La información de la cadena “realm” es una cadena arbritaria enviada para mostrar al usuario un recordatorio del tipo de autentificación. La imagen del punto 4 muestra como la caja de diálogo de mozilla pide la autentificación mostrando el realm y el host. El usuario rellena el formulario y lo envía. El navegador automáticamente reenvía la petición como vemos en el paso 5. Aquí es donde vemos que se han añadido algunos campos en la petición HTTP estándar. Authorization: Basic ZWNhc2JhczpwcnVlYmE=\r\n Aquí es donde el navegador web envía la información de la autorización actual al servidor. El campo “Authorization” se ve como está compuesto por dos valores. La palabra “Basic” muestra como el login esta siendo enviado de acuerdo al método de autentificación básica. El bloque de datos que le sigue es el actual login enviado por el navegador. Nuestros datos de login no aparecen directamente, pero no es una rutina de encriptación, es una codificación en base 64. A modo resumen, la codificación en base64 representa secuencias arbitrarias de octetos de una forma no necesariamente legible por los humanos. Los algoritmos de codificación y decodificación son simples pero los datos codificados suelen ser un 33% más grandes que los datos sin codificar. Para más información sobre esta codificación consultar en los enlaces del final del documento. Código perl para decodificar una cadena en base64 como la anterior. --codigo perl-#!/usr/bin/perl use MIME::Base64; while (<>) { print MIME::Base64::decode_base64($_); } -Con el código anterior, el login en texto plano, puede ser trivialmente decodificado al subyacente formato de usuario:password. ZWNhc2JhczpwcnVlYmE= --> base64Decode() --> “ecasbas:prueba” La implementación de la autentificación “digest” es exáctamente el mismo proceso que la autentificación básica anterior, la única diferencia está en el número de argumentos suministrados por el navegador y en el formato de el login devuelto. Ambos tipos de autentficiación “digest” y “basic” son utilizadas por los clientes y servidores web, sin embargo, no deberían ser utilizados como un grado de protección para información sensible o accesos seguros. Es común utilizar el mismo usuario y contraseña para diferentes servicios, en estos casos habría que tener en cuenta, que los recursos que queremos proteger con este método, no sean recursos muy comprometidos, y que las credenciales no funcionen en otro servicio como puede ser el correo o acceso a información personal. 3. AUTENTIFICACIÓN PROXY. Las secuencias anteriores son de un cliente pidiendo un recurso protegido a un servidor web. Pero lo mismo se aplicaría cuando un proxy requiere validación para acceder a un recurso. Variando el contexto y alguna cabecera HTTP. A continuación se exponen los pasos que componen este método de autentificación: 1. Un usuario con proxy configurado en navegador, solicita acceso a un recurso web (por ejemplo un buscador) 2. El servidor proxy comprueba que ese usuario necesita validación para poder navegar y le envía al cliente un desafío de password con la cabecera HTTP “Proxy Authenticate” y código 407. 3. El navegador del usuario recibe el código y la cabecera de authorización y muestra el diálogo de usuario/contraseña. Cuando el usuario introduce los datos, el navegador realiza una codificación en base64 con los datos introducidos y lo reenvía al servidor proxy en la cabecera del cliente “Proxy-Authorization”. 4. El servidor proxy decodifica el nombre de usuario y password, y comprueba que tiene acceso para poder navegar. 3.1 EJEMPLO PRÁCTICO. . Paquetes capturados con ethereal en una conexión solicitando un acceso a internet con un servidor proxy requiriéndonos validación para ello. 1. Con un servidor proxy configurado en nuestro navegador, realizamos una petición para poder navegar. GET http://www.google.com/ HTTP/1.1\r\n Host: www.google.com\r\n User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Accept: application/x-shockwave-flash,text/xml,application/xml,*/*;q=0.1\r\n Accept-Language: en-us,en;q=0.7,es;q=0.3\r\n Accept-Encoding: gzip,deflate\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n Keep-Alive: 300\r\n Proxy-Connection: keep-alive\r\n 2. El proxy nos contesta indicándonos que necesitamos validarnos para poder navegar. HTTP/1.0 407 Proxy Authentication Required\r\n Server: squid/2.5.STABLE12\r\n Mime-Version: 1.0\r\n Date: Mon, 16 Jan 2006 13:01:19 GMT\r\n Content-Type: text/html\r\n Content-Length: 3283\r\n Expires: Mon, 16 Jan 2006 13:01:19 GMT\r\n X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0\r\n Proxy-Authenticate: Basic realm=""Proxy Authentication (user/passwd)""\r\n X-Cache: MISS from proxy.es\r\n Proxy-Connection: keep-alive\r\n 3. Entonces nuestro navegador lo interpreta como un desafío/respuesta de autentificación básica y nos muestra el login para introducir los datos requeridos. Algunos navegadores no interpretan bien el “realm” por lo que en algunos si que se verá en el cuadro anterior el mensaje “Proxy Authentication (user/passwd)”, este no es el caso como se puede ver, pero nos sirve para el ejemplo. 4. Introducimos usuario y password y nuestro cliente envía los siguientes datos de vuelta al proxy. GET http://www.google.com/ HTTP/1.1\r\n Host: www.google.com\r\n User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Accept: application/x-shockwave-flash,text/xml,image/gif;q=0.2,*/*;q=0.1\r\n Accept-Language: en-us,en;q=0.7,es;q=0.3\r\n Accept-Encoding: gzip,deflate\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n Keep-Alive: 300\r\n Proxy-Connection: keep-alive\r\n Proxy-Authorization: Basic ZWNhc2Jhc0B1bmF2LmVzOnBydWViYTAx\r\n 5. El servidor proxy comprueba internamente que efectivamente el usuario y password son válidos y nos da acceso al recurso. HTTP/1.0 200 OK\r\n Cache-Control: private\r\n Content-Type: text/html\r\n Content-Encoding: gzip\r\n Server: GWS/2.1\r\n Content-Length: 1408\r\n Date: Mon, 16 Jan 2006 13:05:40 GMT\r\n X-Cache: MISS from filter\r\n Proxy-Connection: keep-alive\r\n En lugar de contestar con un código 401 de HTTP, al tratarse de un servidor proxy, muestra el código 407 (autentficación de proxy requerida), y la cabecera que añadía WWW-authenticate el servidor web, ahora al tratarse de un proxy, añade la cabecera Proxy-Authenticate. Y todo el proceso sería idéntico que el de un acceso a un recurso web restringido, pero con estas mínimas diferencias. Resumen Tabla 1. Autentificación de servidor web y autentificación proxy. Servidor Web Servidor Proxy. Código de estado sin autorización: 401 Código de estado sin autorización: 407 WWW-authenticate Proxy-Authenticate Authorization Proxy-authorization Authentication-Info Proxy-Authentication-Info. 4. CONCLUSIONES “Any service in present use that uses Basic should be switched to Digest as soon as practical.”, (extraido del RFC 2617: HTTP Authentication: Basic and Digest Access Authentication) La autentificación básica de HTTP es simple y conveniente, pero no es un método seguro. Se debería usar en casos donde el acceso a información se desea que fuera privado, pero no como un requisito absolutamente necesario, y donde su uso no pueda comprometer la seguridad de otros sistemas. Las personas tienden a utilizar el mismo usuario y password para múltiples propósitos, por lo que aunque su uso se haga dentro de entornos fiables y para acceso a información no sensible, siempre existirá el riesgo de que esas mismas credenciales nos den acceso a servicios mas críticos como correo electrónico, documentos personales, bases de datos.. Con un sniffer de red, y unos cuantos scripts apropiados para interpretar el tráfico capturado, en cuestión de minutos, es posible obtener cientos de pares “usuarios/contraseñas” con el método descrito anteriormente. Con la autentificación HTTP, las contraseñas viajan en claro por la red, y en términos de una conexión, las cabeceras con los passwords, no viajan sólo una vez (la primera vez que se valida), sino durante todo el tiempo que dure la conexión y en cada transacción que se haga se vuelven a enviar, esto es por la característica del protocolo HTTP que no conserva estado, y es necesario recordar los datos que se suministran en cada conexión que se hace con el servidor web o proxy. Para mejorar este método de autentificación, o sustituirlo por otros más seguros sería conveniente: – Combinar con SSL para reforzar la seguridad encriptando todos los datos de la transmisión. – Sustituir por la autentificación digest. – ¿CAS Project?. – ¿Webiso? Documentos consultados. Autentifcación HTTP: Autentificación de acceso Basic y digest ftp://ftp.isi.edu/in-notes/rfc2617.txt Codificación de transferencia de contenido en Base64 http://www.faqs.org/rfcs/rfc2045.html Configurar apache para requerir autentificación. http://httpd.apache.org/docs/1.3/howto/auth.html CAS project. http://www.ja-sig.org/wiki/display/CAS/Home RFC 2617 http://rfc.sunsite.dk/rfc/rfc2617.html