Hace unos meses compartí un artículo que explicaba cómo verificar la seguridad de un servidor Web con el Observatorio de Mozilla.
El "observatorio" es un proyecto enfocado a ayudar a desarrolladores, administradores y expertos en seguridad a configurar sus sistemas de forma segura. Se trata de un escáner en línea capaz de verificar que los servidores Web implementen correctamente las medidas de seguridad adecuadas. Sin embargo, Mozilla además provee un cliente de línea de comandos que permite realizar escaneos de servidores desde nuestra terminal:
github.com/mozilla/observatory-cli
Esto permite la posibilidad de correr baterías de tests sobre varios servidores, para analizar luego los resultados e integrarlos con nuestros scripts de seguridad.
La instalación del cliente se hace a través del gestor de módulos de Node, npm
. Para instalar npm
en FreeBSD ejecutar:
% sudo pkg install npm
En Debian y derivados, ejecutar apt-get install npm
.
Para instalar el cliente del Observatorio de Mozilla, ejecutar:
% sudo npm install -g observatory-cli
En los sistemas FreeBSD, npm
instala los módulos en el directorio /usr/local/lib/node_modules/
:
emi@hal9000:~ % ll /usr/local/lib/node_modules/observatory-cli/ total 392 -rw-r--r-- 1 nobody wheel 616 Oct 10 2016 .eslintrc.yml -rw-r--r-- 1 nobody wheel 39 Oct 10 2016 .npmignore -rw-r--r-- 1 nobody wheel 343 Oct 11 2016 Dockerfile -rw-r--r-- 1 nobody wheel 7169 Oct 11 2016 README.md -rw-r--r-- 1 nobody wheel 112363 Oct 11 2016 docker_example.png -rw-r--r-- 1 nobody wheel 7127 Sep 27 2016 example-curl.txt -rwxr-xr-x 1 nobody wheel 13016 Oct 17 2016 index.js* drwxr-xr-x 70 root wheel 1536 Jun 6 09:41 node_modules/ -rw-r--r-- 1 nobody wheel 3056 Jun 6 09:41 package.json -rw-r--r-- 1 nobody wheel 225251 Oct 10 2016 report.png -rw-r--r-- 1 nobody wheel 217 Oct 11 2016 server.js drwxr-xr-x 3 nobody wheel 512 Jun 6 09:41 shell_functions/
Para escanear un sitio, simplemente ejecutar observatory
con el nombre de dominio como parámetro:
% observatory www.linuxito.com
Por ejemplo:
emi@hal9000:~ % observatory www.linuxito.com { "content-security-policy": { "expectation": "csp-implemented-with-no-unsafe", "name": "content-security-policy", "output": { "data": null }, "pass": false, "result": "csp-not-implemented", "score_description": "Content Security Policy (CSP) header not implemented", "score_modifier": -25 }, "redirection": { "expectation": "redirection-to-https", "name": "redirection", "output": { "destination": "http://www.linuxito.com/", "redirects": false, "route": [ "http://www.linuxito.com/" ], "status_code": 200 }, "pass": false, "result": "redirection-missing", "score_description": "Does not redirect to an https site", "score_modifier": -20 }, "strict-transport-security": { "expectation": "hsts-implemented-max-age-at-least-six-months", "name": "strict-transport-security", "output": { "data": null, "includeSubDomains": false, "max-age": null, "preload": false, "preloaded": false }, "pass": false, "result": "hsts-not-implemented", "score_description": "HTTP Strict Transport Security (HSTS) header not implemented", "score_modifier": -20 }, "x-content-type-options": { "expectation": "x-content-type-options-nosniff", "name": "x-content-type-options", "output": { "data": null }, "pass": false, "result": "x-content-type-options-not-implemented", "score_description": "X-Content-Type-Options header not implemented", "score_modifier": -5 }, "x-frame-options": { "expectation": "x-frame-options-sameorigin-or-deny", "name": "x-frame-options", "output": { "data": null }, "pass": false, "result": "x-frame-options-not-implemented", "score_description": "X-Frame-Options (XFO) header not implemented", "score_modifier": -20 }, "x-xss-protection": { "expectation": "x-xss-protection-1-mode-block", "name": "x-xss-protection", "output": { "data": null }, "pass": false, "result": "x-xss-protection-not-implemented", "score_description": "X-XSS-Protection header not implemented", "score_modifier": -10 } }
La salida del scan se presenta en formato JSON y presenta el detalle de todos los tests que no fueron pasados:
- "content-security-policy": verifica si el header CSP permite keywords
unsafe-
. - "redirection": verifica si el sitio http redirige automáticamente al sitio https (HTTPS forzado).
- "strict-transport-security": verifica si el header HTTP Strict Transport Security (HSTS) está configurado a un mínimo de seis meses.
- "x-content-type-options": verifica si el header X-Content-Type-Options está implementado correctamente.
- "x-frame-options": verifica si X-Frame-Options (XFO) está configurado en
SAMEORIGIN
oDENY
. - "x-xss-protection": verifica si el header X-XSS-Protection está implementado.
- "public-key-pinning: verifica que HTTP Public Key Pinning (HPKP) está implementado correctamente.
- "cross-origin-resource-sharing": verifica que el contenido no sea accesible via CORS.
- "subresource-integrity": verifica que se implemente SRI en caso de que contenido sea cargado desde diferente origen.
- "cookies": verifica si las cookies son enviadas de forma segura y se utiliza el flag HttpOnly.
- "referrer-policy": verifica si el header Referrer-Policy está implementado.
Si se desea obtener directamente un reporte, utilizar la opción --format=report
:
emi@hal9000:~ % observatory www.linuxito.com --format=report HTTP Observatory Report: www.linuxito.com Score Rule Description -25 content-security-policy Content Security Policy (CSP) header not implemented. -20 redirection Does not redirect to an https site. -20 strict-transport-security HTTP Strict Transport Security (HSTS) header not implemented. -20 x-frame-options X-Frame-Options (XFO) header not implemented. -10 x-xss-protection X-XSS-Protection header not implemented. -5 x-content-type-options X-Content-Type-Options header not implemented. Score: 0 Grade: F Full Report Url: https://observatory.mozilla.org/analyze.html?host=www.linuxito.com
Esta salida muestra el puntaje otorgado y cuánto se deduce por cada ítem. El puntaje ideal es 100. Sin embargo esta salida no es completa, pues no muestra cuáles test se pasaron. Para ello, agregar la opción -z
:
emi@hal9000:~ % observatory www.linuxito.com --format=report HTTP Observatory Report: www.linuxito.com Score Rule Description -25 content-security-policy Content Security Policy (CSP) header not implemented. -20 redirection Does not redirect to an https site. -20 strict-transport-security HTTP Strict Transport Security (HSTS) header not implemented. -20 x-frame-options X-Frame-Options (XFO) header not implemented. -10 x-xss-protection X-XSS-Protection header not implemented. -5 x-content-type-options X-Content-Type-Options header not implemented. 0 public-key-pinning HTTP Public Key Pinning (HPKP) header not implemented. 0 contribute Contribute.json isn't required on websites that don't belong to Mozilla. 0 cross-origin-resource-sharing Content is not visible via cross-origin resource sharing (CORS) files or headers. 0 subresource-integrity Subresource Integrity (SRI) not implemented, but all scripts are loaded from a similar origin. 0 cookies No cookies detected. 0 referrer-policy Referrer-Policy header not implemented. Score: 0 Grade: F Full Report Url: https://observatory.mozilla.org/analyze.html?host=www.linuxito.com
El test del Observatorio es muy estricto. Apunta a alcanzar el máximo nivel de seguridad posible. Para mitigar todas estas vulnerabilidades, Mozilla ofrece dos guías de seguridad SSL y Web muy interesantes:
Tener en cuenta que el cliente en sí no es quien realiza los tests, sino que interactúa contra el Observatorio de Mozilla (observatory.mozilla.org/). Por esta razón, esta herramienta no sirve para escanear servidores internos, ya que estos deben ser accesibles desde Internet.
Referencias
- Observatory by Mozilla CLI Client
- Content Security Policy - Google Developers
- Forzar HTTPS en Apache
- HTTP Strict Transport Security Cheat Sheet
- X-Frame-Options
- X-XSS-Protection
- X-Content-Type-Options
- HTTP Public Key Pinning (HPKP)
- HTTP access control (CORS)
- Subresource Integrity
- HttpOnly
- Referrer-Policy
Fuente: linuxito