Implementing Security

Problem

How to secure protected areas of your web applications and prevent common known exploits?

Solution

There are several best practices mentioned here in this guide that will help with security.  Please note this guide is only concerned with the UI portion of a secured web application.  And as the saying goes, no web applications are 100% secure.  Check the security advisory on a regular basis for vulnerability reports.  Here are our topics for this section:


Authentication and Authorization

ACT web applications uses JLink Single-Sign-On (SSO) for authentication. The roles for each authenticated users are also available via JLink SSO. JLink has provided a servlet filter to to integrate with SpringMVC. If you use the web application template from the getting started guide, the servlet filter should be setup for you already with the default jsecurityType.

To configure it, go into web/WEB-INF/web.xml and replace the default jsecurityType to the one appropriate to your web application and setup the URL pattern that the servlet filter will be intercepting. For example, if you want Student.Transactional for URL pattern /student, specify the jsecurityType here:

<!-- jlink security filter -->
<filter>
<filter-name>jlinkSecurityStudentFilter</filter-name>
    <filter-class>
        edu.ucsd.act.jlink.filters.JLinkSecurityFilter</filter-class>
    <init-param>
        <param-name>jsecurityType</param-name>
        <param-value>Student.Transactional</param-value>
    </init-param>
    <init-param>
        <param-name>defaultUrl</param-name>
        <param-value>/hello/home.htm</param-value>
    </init-param>
</filter>

And specify the URL pattern here:

<!-- jlink security filter mapping -->
<filter-mapping>
    <filter-name>jlinkSecurityStudentFilter</filter-name>
    <url-pattern>/student/*</url-pattern>
</filter-mapping>

Mitigate Cross-site Scripting

Cross-site Scripting (XSS) is one of the most common vulnerabilities with a web applications.  To mitigate it, validate and escape the input data from user during processing on the server.  Visit building a form guide for more information on validation.  To escape user data, you can do that in three ways in Spring MVC:

Global Level

All form tags are escaped.

<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

Page Level

All form tags in a targeted page are escaped

<spring:htmlEscape defaultHtmlEscape="true" />

Tag Level

A form tag is escaped

<form:input path="name" htmlEscape="true" />

If you use the web application template from the getting started guide, a global level escape has already been setup as default.

Mitigate Cross-site Scripting (Jlink)

Cross-site Scripting Filter

to be added FIRST to the filter definitions in the web.xml

public class CrossScriptingFilter implements Filter
{
   public void init( FilterConfig filterConfig ) throws ServletException
   {
   }
    public void destroy()
    {
    }
    public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException
    {
    HttpServletResponse res = (HttpServletResponse)response;
    res.addHeader("X-FRAME-OPTIONS", "SAMEORIGIN" );
       chain.doFilter( new XSSRequestWrapper( (HttpServletRequest) request ), response );
    }
}

XSSRequestWrapper

This does the actual filtering of input parameters. YOU WILL NEED TO TEST YOUR APP THOROUGHLY after adding this. It has the potential of stripping out items that your app may need.

web.xml


Auto Binding

You should be familiar with Building a Form before proceeding with this section.

If an application is binding data directly to a domain model instead of a form model, some of domain model's fields can be exposed to the client.  Best practice is to use a form model that only contains fields you want to bind, or to specify what fields you want to bind if binding to a domain model.  To specify when using the @Controllerannotation, use the @InitBinder annotation to inject a WebDataBinder into a method used to configure it explicitly.  Call setAllowedFields(String []) or setDisallowedFields(String[]) to restrict the fields allowed for that Controller class.

private static final String[] ALLOWED_FIELDS = {"name", "password", "userInfo.phone", "userInfo.email"};
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
    dataBinder.setAllowedFields(ALLOWED_FIELDS);
}

If the set of allowedFields needs to vary per handler method, have your @InitBinder method accept a HttpServletRequest and key off the current request mapping.


ModelView Injection

You should be familiar with Navigation before proceeding with this section.

Never allow the client to select the view name. View name selection is a server-side responsibility.

Trust no one.