|
Version 4.10.0 | ||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
---|---|
ApplicationFirewall | Perform hard validation on each incoming request. |
FetchIdentifierOwner | Look up the login name of the user who owns an untrusted identifer. |
LoginTasks | Perform tasks required after successful user login. |
PermittedCharacters | Characters accepted by the SafeText class. |
SpamDetector | Determine if text is likely spam. |
UntrustedProxyForUserId | Determines if a request has an ownership constraint which needs explicit validation for a user id proxy. |
Class Summary | |
---|---|
ApplicationFirewallImpl | Default implementation of ApplicationFirewall . |
CsrfFilter | Protect your application from a Cross Site Request Forgery (CSRF). |
PermittedCharactersImpl | Default implementation of PermittedCharacters . |
SafeText | Models free-form text entered by the user, and protects your application from Cross Site Scripting (XSS). |
SpamDetectorImpl | Fails all text containing links, except those appearing in wiki-style formatting. |
SuppressUnwantedSessions | Suppress the creation of unwanted sessions. |
UntrustedProxyForUserIdImpl | Default implementation of UntrustedProxyForUserId . |
Tools for making your web application more secure.
The Open Web App Security Project (OWASP) is an excellent guide for increasing the security of your web application, and is highly recommended.
An important point to understand is the separation of validation into two distinct parts -
hard validation, and soft validation - see ApplicationFirewall
for more information.
SafeText
, not String.
This provides protection against XSS (Cross Site Scripting) attacks, without forcing you to continually
escape special characters in JSPs.
<%@ page contentType="text/html" %>Such directives must appear at the start of the page.
The jsp-property-group setting in web.xml can specify an include-prelude JSP, which will be automatically included at the start of your JSPs.
CsrfFilter
should be configured, to
protect against CSRF attacks.
This filter requires configuration for FormSourceIdRead and FormSourceIdWrite. These items reference SqlIds. As usual, these SqlIds need to be declared in one of your application's classes, and also appear in an .sql file. (This ensures the usual matching of .sql file content to SqlIds will not fail. See hirondelle.web4j.database for more information.)
ApplicationFirewallImpl
provided by the framework is an
excellent default for the ApplicationFirewall
interface. It performs sanity checks on
every request, to make sure they aren't hacks.
You can subclass that implementation in order to add further checks, if desired.
(Replacing the implementation entirely is possible, but is usually an extensive task, and should likely be
attempted only if you are experienced.)
SpamDetector
interface can vary widely. The
SpamDetectorImpl
is a simple default, but you will occasionally need to replace it with
something more appropriate> This will usually be easy to implement.
SafeText
class is provided as the main defense against
XSS attacks. The SafeText.toString()
method performs proper escaping for HTML, and SafeText.getXmlSafe()
performs proper
escaping for XML documents. For the most common case of presenting data in a web page, a SafeText
object will be rendered safely by default.
It is highly recommended that all free-form text input by the user be represented in a Model Object using SafeText instead of String.
Using SafeText will greatly increase your safety when using JSTL. The JSTL is a bit defective when it comes to protecting you from XSS attacks:
CsrfFilter
is provided as a defense against CSRF attacks.
To use it, you must have the CsrfFilter configured as a Servlet Filter in web.xml. As part of that configuration, you must provide two SqlId's, to tell the Filter what SQL statements to use to read and write 'form-source ids', the tokens used to identify forms generated by your web app.
Although it is not really necessary for those simply wanting to use CsrfFilter, the following is a description of its implementation.
CsrfFilter
will create a 'form-source id', and store it in the
user's session under the key 'web4j_key_for_form_source_id'.
This form-source id is constant for each session, and is hard to guess.
The CsrfFilter will automatically modify all of your forms having method='POST'
to include a hidden request parameter of the same name (web4j_key_for_form_source_id),
whose value is simply the value created upon login.
ApplicationFirewallImpl
will verify that each POSTed
form includes a parameter named web4j_key_for_form_source_id, and that its value matches either
the current value stored in the user's session, or the form-source id used in the immediately preceding
session for the same user.
The form-source id used in the previous session is needed to ensure smooth behavior upon re-login. Here is the use case in more detail :
When the form is POSTed, the user will of course need to log in a second time. After successful authentication, the action will continue in the usual way. In this case, however, note that there is a new session. Thus, the old form-source id attached to the first session is POSTed, not the current one. What is to be done? Well, if this use case is to be handled gracefully, then the 'old' form-source id must be remembered (in the database) and treated as second valid value. Then, a POSTed form will succeed only if its web4j_key_for_form_source_id has either the current form-source id value, or the 'old' form-source id value of the immediately preceding session.
This is the reason for the two SqlId configuration settings for the CsrfFilter: they tell the Filter how to read and write the form-source id for a given user. This allows the Filter to remember the previous form-source id value for each user.
When a user logs out, or when a session is about to expire, CsrfFilter will extract the user's form-source id from the session, and store it in the database for possible future use.
ActionImpl.createSessionAndCsrfToken()
(typically in the Action's constructor).
There is one difference when a session does not include a user login: when a session expires, there's no way to recover using a 'previous' token from a previous session. Again, this is because the session is not attached to a specific user.
|
Version 4.10.0 | ||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |