openxava / documentación / Seguridad web (OWASP)

Tabla de contenidos

Seguridad web (OWASP)
Configurar tu aplicación
Páginas de error
Same site cookies
Configurar aplicación ROOT
Desactivar la seguridad web
A partir de OpenXava 7.3 tus aplicaciones pueden cumplir con OWASP Top Ten, lo que significa contar con los máximos estándares de seguridad para aplicaciones web. De hecho, OpenXava pasa la prueba de seguridad web ZAP de OWASP al 100%, sin ninguna alerta de nivel crítico, medio o bajo.
Esto no significa que las aplicaciones hechas con OpenXava sean automáticamente seguras o cumplan automáticamente con el OWASP Top Ten, porque tu propio código podría ser vulnerable, podrías usar librerías propias vulnerables, podrías no configurar correctamente tu aplicación, no configurar correctamente tu servidor de aplicaciones o desactivar alguna característica de seguridad de OpenXava. Por eso, es importante que pases tu mismo la prueba ZAP sobre tu aplicación, o incluso contrates a un auditor de seguridad para que verifique la seguridad de tu aplicación y el cumplimientos de los estándares requeridos.

Configurar tu aplicación

Cuando ejecutas tu aplicación en desarrollo, OpenXava usa un Tomcat embebido configurado para cumplir con todos los requisitos de seguridad necesarios para pasar el ZAP. Sin embargo, cuando generas un WAR y lo despliegas en tu Tomcat de producción, puede que tu aplicación no sea completamente segura, ni pase el ZAP. Tienes que configurar algunos detalles.

Páginas de error

Para pasar el ZAP las páginas de error no pueden ofrecer información sobre el servidor que se está usando y menos aún visualizar una traza de error. Cuando arrancas la aplicación desde el Tomcat embebido para desarrollo ya está configurada para ofrecer páginas de error seguras. También si tu aplicación fue creada con OpenXava 7.3 o superior, las páginas de error ya vienen bien configuradas. Pero si tu aplicación la creaste con un OpenXava anterior a v7.3 y estás desplegando un WAR en un Tomcat, tendrás que añadir lo siguiente en el web.xml de tu aplicación, que está situado en src/main/webapp/WEB-INF de tu proyecto:
<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/error404.html</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/error500.html</location>
</error-page>
No hace falta crear error404.html ni error500.html, porque están incluidos en openxava.jar.

Same site cookies

Lo mismo ocurre con la configuración de las cookies. Si usas el Tomcat embebido o tu aplicación fue creada con v7.3+ no hay problema, pero en caso contrario has de de definir Same Site Cookies como Lax en el context.xml, situado en src/main/webapp/META-INF. Añade la entrada <CookieProcessor sameSiteCookies="lax" />, como ves aquí:
<Context>
    <JarScanner scanClassPath="false" />
    <CookieProcessor sameSiteCookies="lax" /> <!-- AÑADIR ESTA LÍNEA -->
  
    ...

Configurar aplicación ROOT

El test ZAP además de analizar la URL de la aplicación que le indicas, también hace algunas comprobaciones en el contexto raíz de donde está desplegada tu aplicación. El contexto raíz en el Tomcat lo define la aplicación ROOT, si no tienes control sobre la aplicación ROOT o no te importa ignorar las indicaciones que te haga el ZAP sobre el contexto raíz, no hace falta que hagas nada. Ahora bien, si quieres pasar el ZAP al 100% con tu WAR desplegado en el Tomcat tendrás que asegurarte de que aplicación raíz genere cabeceras CSP y la cabecera X-Content-Type-Options.
Por desgracia, no hay una forma rápida de configurar el Tomcat para esto. Tendrás que escribir el código de un filtro que genere esas cabeceras. El siguiente código te puede servir:
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;

@WebFilter("/*") 
public class ContentSecurityPolicyFilter implements Filter {
	
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setHeader("Content-Security-Policy", "default-src 'self'; frame-ancestors 'self'; form-action 'self';");
        httpResponse.setHeader("X-Content-Type-Options", "nosniff");
        chain.doFilter(request, response);
    }
	
    public void init(FilterConfig cfg) throws ServletException { // Para Tomcat 8.x
    }
	
    public void destroy() { // Para Tomcat 8.x
    }
	
}
Compila la clase y déjala dentro de webapps/ROOT/WEB-INF/classes de tu Tomcat, en la misma estructura de carpeta del paquete en que hayas escrito la clase. Es decir, si la clase están en el paquete com.tuempresa.raiz.filtros el ContentSecurityPolicyFilter.class deberías dejarlo en la carpeta webapps/ROOT/WEB-INF/classes/com/tuempresa/raiz/filtros de tu Tomcat.
Para que reconozca el filtro tienes que asegurarte de que metadata-complete sea false en web.xml de ROOT:
<web-app 
    ...
    metadata-complete="false">
    
    ...

Finalmente deberías descargar el ZAP y pasarlo sobre tu aplicación desplegada en tu Tomcat.

Desactivar la seguridad web

No es buena idea desactivar la seguridad, pero si tu aplicación no requiere cumplir una normativa de seguridad estricta y va a ser ejecutada en un entorno seguro, puede haber ocasiones en que sea conveninente desactivar la seguridad web total o parcialmente. Esto puede ser necesario si tenemos mucho código web propio antiguo que no sigue las buenas prácticas de seguridad o si usamos librerías de tercero que tampoco la cumplen.
En concreto OpenXava, desde la versión 7.3, tiene una Content Security Policy (CSP) estricta. Esto quiere decir que se le instruye al navegador para que no haga cosas que pueden ser peligrosas, en potencia. Lo cual a su vez restringe las cosas que se pueden usar.
Por ejemplo, solo se pueden descargar imágenes, scripts, CSSs o abrir frames provenientes de  la misma dirección desde donde se ha descargado la aplicación. Si necesitamos descargar recursos desde otro sitio, se puede hacer añadiendo las propiedades trustedHostsForImages, trustedHostsForScripts, trustedHostsForStyles y trustedHostsForFrames en el archivo xava.properties de nuestro proyecto, como en este ejemplo:
trustedHostsForImages=https://openxava.org/
trustedHostsForScripts=https://openxava.org/
trustedHostsForStyles=https://openxava.org/
trustedHostsForFrames=https://openxava.org/
En este ejemplo está permitido descar imagenes, JavaScript, CSSs y abrir iframes desde openxava.org. Usar estas propiedades no es peligroso si la direcciones que ponemos son de confianza. Podemos poner varias separadas por comas.
Por otra parte, por defecto la CSP está configurada para no permitir el uso de eval() en JavaScript, si tenemos código propio que usa eval() o una librería de terceros que lo necesite, podemos habilitar el uso de eval() con la siguiente línea en xava.properties:
unsafeEvalInScripts=true
Habilitar el uso de eval() es peligroso siempre, por eso esto debería ser una medida temporal y tendrías que ir pensando en reescribir tu código para no usar eval() o actualizar la librería de JavaScript correspondiente.
Además, la cabecera de Content Security Policy (CSP) se puede desactivar completamente. Añade a xava.properties:
turnOffWebSecurity=true
Hacer esto es una forma rápida de ver tu aplicación funcionando si has actualizado a la versión 7.3+ desde una version antigua de OpenXava, pero constituye un riesgo de seguridad importante, porque la CSP estricta es lo que permite inhibir la mayor parte de los riesgos de seguridad.