June 19, 2018

(Mis)Configure web.xml in Java EE 6

Since Java EE 6 you can have EJB in a war, which means you can also configure EJB, MDB and JNDI lookup in web.xml, but here we will only look at the web configuration in the web.xml and especially the security configuration settings.

Below follows all possible web configuration settings in Java EE 6.


module-name
  
distributable

context-param

filter
  
filter-mapping

listener

servlet

servlet-mapping

session-config
    session-timeout
    cookie-config
        name    # default JSESSIONID
        domain
        path
        comment
        http-only
        secure
        max-age # in seconds, default -1
    tracking-mode

mime-mapping

welcome-file-list

error-page
    error-code | exception-type
    location

jsp-config

security-constraint
    display-name
    web-resource-collection
        web-resource-name
        description
        url-pattern
        http-method
        http-method-omission
    auth-constraint
        description
        role-name
    user-data-constraint
        description
        transport-guarantee # [NONE|INTEGRAL|CONFIDENTIAL] Use CONFIDENTIAL for HTTPS

login-config
    auth-method # [BASIC|DIGEST|FORM|CLIENT-CERT]
    realm-name # The realm name element specifies the realm name to use in HTTP Basic authorization.
    form-login-config
        form-login-page
        form-error-page

security-role
    description
    role-name

message-destination

locale-encoding-mapping-list

And a complete web.xml example containing all security settings.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <module-name>example-ee7-web</module-name>

    <distributable />

    <session-config>
        <!-- Session timeout after X MINUTES after no user interaction. -->
        <session-timeout>60</session-timeout>
        <cookie-config>
            <!-- XSS attack: make sure that cookie cannot be accessed via client 
                side scripts. -->
            <http-only>true</http-only>
            <!-- CSRF attack, session hijack attack: require cookie can only be used 
                for SSL communication. -->
            <secure>true</secure>
        </cookie-config>
        <!-- Do not use URL, since then it can be stored in numerous places: browser 
            history, proxy server log, referrer logs, web logs, etc. -->
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>

    <welcome-file-list>
        <welcome-file>/index.html</welcome-file>
        <welcome-file>/index.jsp</welcome-file>
        <welcome-file>/index.jsf</welcome-file>
    </welcome-file-list>

    <error-page>
        <error-code>400</error-code>
        <location>/400.html</location>
    </error-page>
    <error-page>
        <error-code>401</error-code>
        <location>/401.html</location>
    </error-page>
    <error-page>
        <error-code>403</error-code>
        <location>/403.html</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/500.html</location>
    </error-page>
    <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/500.html</location>
    </error-page>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Protected pages</web-resource-name>
            <!-- Add multiple 'url-pattern' for below 'auth-constraint > role-name'. -->
            <url-pattern>/*</url-pattern>
            <!-- Do not specify http-method, since then only specified http-method 
                will be authenticated, not e.g. JUNK (attack). -->
        </web-resource-collection>
        <auth-constraint>
            <!-- Add multiple 'role-name' for above 'url-pattern'. -->
            <role-name>GRP_ALL_USERS</role-name>
        </auth-constraint>
        <user-data-constraint>
            <!-- Force HTTPS to access web application. -->
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>CLIENT-CERT</auth-method>
    </login-config>

    <!-- All referenced roles in application. Use multiple 'security-role > role-name' 
        for more. -->
    <security-role>
        <role-name>GRP_ALL_USERS</role-name>
    </security-role>
</web-app>