Flask sitio penetration tests: security headers y el session cookie
Penetration testing es una forma fácil de comprobar si su sitio es vulnerable a ataques maliciosos.
Ha creado una aplicación web Flask , que funciona bien y utiliza https. ¿Pero es lo suficientemente seguro? ¿Hizo todo lo posible para proteger a sus visitantes, hizo todo lo posible para evitar los ataques maliciosos?
Una buena manera de proceder en esto es a pentest su sitio. Las herramientas Penetration testing , o las herramientas pen testing , pueden identificar las debilidades de seguridad. Identifican las vulnerabilidades en la aplicación web que pueden causar una brecha de seguridad.
Wikipedia: El National Cyber Security Center, describe la prueba de penetración como lo siguiente: "Un método para obtener garantías en la seguridad de un sistema de TI mediante el intento de violar parte o toda la seguridad de ese sistema, utilizando las mismas herramientas y técnicas que podría utilizar un adversario".
La mayoría de las herramientas de pentest deben ser instaladas y por supuesto no en su máquina local sino en algún lugar de Internet para que pueda probar su sitio de producción sin pasar por firewalls, NAT. Algún día examinaré estas herramientas con más detalle, pero por ahora sólo quería tener alguna indicación de posibles vulnerabilidades.
Utilicé una prueba en línea de Pentest-Tools.com, ver el enlace de abajo, se obtienen dos pruebas gratuitas. Seleccione el Website Vulnerability Scanner, ingrese la url de su sitio y siéntese a esperar los resultados. Por supuesto, esta es una prueba muy, muy básica, pero al menos me mostró que a mi sitio le faltaba security headers y que el session cookie no era seguro. También usé Dareboost, ver enlace abajo, su prueba Website Speed Test and Website Analysis me dio un buen reporte de Quality and Performance .
Añadir security headers que falta
Es muy fácil añadir el security headers que falta a su sitio Flask . Primero tengo una función que añade los encabezados extra, uso la bandera include_security_headers para los sitios realmente en internet.
from werkzeug.http import http_date
import datetime
def prepare_response_extra_headers(include_security_headers):
response_extra_headers = {
# always
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
'Last-Modified': http_date(datetime.datetime.now()),
}
if include_security_headers:
response_security_headers = {
# X-Frame-Options: page can only be shown in an iframe of the same site
'X-Frame-Options': 'SAMEORIGIN',
# ensure all app communication is sent over HTTPS
'Strict-Transport-Security': 'max-age=63072000; includeSubdomains',
# instructs the browser not to override the response content type
'X-Content-Type-Options': 'nosniff',
# enable browser cross-site scripting (XSS) filter
'X-XSS-Protection': '1; mode=block',
}
response_extra_headers.update(response_security_headers)
return response_extra_headers
Luego, en create_app() añado las cabeceras extra a la respuesta en after_request:
...
include_security_headers = config_name in ['staging', 'production']
...
# prepare extra response headers, see after_request
response_extra_headers = prepare_response_extra_headers(include_security_headers)
...
@app.after_request
def after_request(response):
# after_request is not called for 500 error
response.headers.extend(response_extra_headers)
return response
Tenga en cuenta que estamos usando extender en lugar de actualizar, vea la información de las estructuras de datos de Werkzeug.
Asegurando el session cookie
Sobre el session cookie, mi sitio está usando https, las peticiones http son redirigidas a https, así que ¿cuál es el problema? El problema es que la cookie no tiene por qué provenir de su navegador en la primera (!) solicitud. Puede establecer el encabezado HTTP Strict Transport Security (HSTS) y aplicar https, pero esto no resuelve el problema porque no todos los navegadores soportan este encabezado.
La única manera de asegurar su session cookie es añadiendo el atributo de seguridad de la cookie. Todavía no estoy seguro de que esto lo resuelva todo, pero no es un esfuerzo para implementarlo. En Flask sólo hacemos:
SESSION_COOKIE_SECURE = True
Si utiliza Flask-Login y la funcionalidad 'remember me', entonces añada también:
REMEMBER_COOKIE_SECURE = True
REMEMBER_COOKIE_HTTPONLY = True
Otro problema de seguridad (sin solución): contraseñas en la memoria
Todavía existe otro problema de seguridad cuando se ejecuta un sitio en un VPS (Virtual Private Server). Las contraseñas se envían por https pero se decodifican en el servidor. Luego, utilizando buenas prácticas, se encriptan y se almacenan en la base de datos.
Incluso si el servidor ha sido parcheado para eliminar vulnerabilidades como Zombieload, una persona que tenga acceso al servidor puede monitorear la memoria del servidor y ver las contraseñas no cifradas. Puede encriptar la contraseña en el cliente usando javascript pero el atacante puede usar este valor encriptado para iniciar la sesión. Lo mínimo que puede hacer es conseguir un proveedor de VPS confiable.
Resumen
Sin la prueba de penetración, usted sólo espera lo mejor. Penetration testing es una muy buena manera de comprobar las vulnerabilidades de su sitio. No es muy difícil, pero toma algo / mucho tiempo. Recuerde que la ejecución de un sitio en un VPS nunca es totalmente segura.
Enlaces / créditos
40 Best Penetration Testing (Pen Testing) Tools in 2020
https://www.guru99.com/top-5-penetration-testing-tools.html
Cookie Security for Flask Applications
https://blog.miguelgrinberg.com/post/cookie-security-for-flask-applications
Dareboost
https://www.dareboost.com/en
Data Structures
https://werkzeug.palletsprojects.com/en/0.15.x/datastructures/
HTTP Security Headers Analysis of Top One Million Websites
https://ccdcoe.org/uploads/2018/10/Art-18-HTTP-Security-Headers-Analysis-of-Top-One-Million-Websites.pdf
Mozilla Observatory
https://observatory.mozilla.org/
Penetration test
https://en.wikipedia.org/wiki/Penetration_test
Pentest-Tools.com
https://pentest-tools.com
Secure your Cookies (Secure and HttpOnly flags)
https://blog.dareboost.com/en/2019/03/secure-cookies-secure-httponly-flags/
Securing Cookies with HttpOnly and secure Flags
https://resources.infosecinstitute.com/securing-cookies-httponly-secure-flags/
Security Headers
https://securityheaders.com/
ZombieLoad attack lets hackers steal data from Intel chips
https://www.theverge.com/2019/5/14/18623708/zombieload-attack-intel-processors-speculative-execution
Leer más
Flask Pentesting
Recientes
- Cómo ocultar las claves primarias de la base de datos UUID de su aplicación web
- Don't Repeat Yourself (DRY) con Jinja2
- SQLAlchemy, PostgreSQL, número máximo de filas por user
- Mostrar los valores en filtros dinámicos SQLAlchemy
- Transferencia de datos segura con cifrado de Public Key y pyNaCl
- rqlite: una alternativa de alta disponibilidad y dist distribuida SQLite
Más vistos
- Usando Python's pyOpenSSL para verificar los certificados SSL descargados de un host
- Usando UUIDs en lugar de Integer Autoincrement Primary Keys con SQLAlchemy y MariaDb
- Conectarse a un servicio en un host Docker desde un contenedor Docker
- Usando PyInstaller y Cython para crear un ejecutable de Python
- SQLAlchemy: Uso de Cascade Deletes para eliminar objetos relacionados
- Flask RESTful API validación de parámetros de solicitud con esquemas Marshmallow