Protecting JSPs from direct access in Struts
By: Emiley J
According to the Model 2 paradigm, the view is always served by the controller and should not be requested explicitly from any other view. In reality a JSP can always navigate to another JSP when the JSPs are placed anywhere in a WAR other than the WEB-INF directory (or its sub-directories). Similarly a user can type in the name of the JSP in the URL bar and invoke the JSP. The web application specification does not disallow such access. Actually this makes sense. The specification should not prevent anybody from coding using the Model 1 paradigm. Consequently your JSPs are exposed to the external world for nosy users to cause unnecessary problems, for hackers to exploit any vulnerability in the system. If you are wondering what the problem is with allowing direct access to JSPs, well, here are some.A nosy user might attempt to guess the JSP name by the operation performed in that page or request parameters or worse – if the page author used html comment tag for SCM and code comments instead of the JSP comments. Armed with this information, the user attempts to access the JSPs directly. A JSP as you know is a view and it displays information based on model objects stored in one of the four scopes – page, request, session or application, the first three being the most common. These objects are created by the back end presentation and business logic and made available for the JSP to act upon. When the JSP is accessed out of context or out of order, the required model objects may not exist in the appropriate scope and consequently almost always leads to the exceptional situations in the JSP code.
It is not common to perform null checks in every bit of code in the JSP tags, scriptlets and other helper classes. These checks are generally limited to interfaces and boundaries between modules and not later on. For instance, in a typical Model 2 scenario, when the model object cannot be created for some reason, the controller instead takes alternate route and displays an alternate view corresponding to the null model object. This assumption of model objects being not null in the main path of the presentation logic and view highly simplifies the coding. In fact when the system is accessed as intended, everything works smoothly. However whenever somebody tries to access the views out of order, all hell breaks lose. Every view starts throwing NullPointerExceptions, IllegalArgumentExceptions and other unchecked and checked exceptions depending on how the JSP page and its tags and scriptlets are authored. This is exactly what a nosy user is trying out.
The implications are even more serious when a malicious user tries to find weak points in the design to bring the system down to its knees. The first thing that might occur is to put checks for nulls and unintended access in the system. Invariably, this is nothing but a collection of if-else blocks in every part of the JSP page making it messy and buggy to maintain.
Two prominent alternatives exist. Let us look the easiest one first. As we glossed over earlier, the servlet specification explicitly states that contents located in the WEB-INF and its sub-directories are protected from outside access.
Let us take a simple example to illustrate this. All contents located in a WAR belong to the same protection domain. A protection domain is a set of entities known (or assumed) to trust each other. Consequently any resource within a WAR can access resources located under WEB-INF directory without restrictions. JSP is also a resource and thus any class within the same WAR can forward to a JSP under WEB-INF. (This part is not explicitly stated in the specification) However when the request originates outside the container, it does not belong to the protection domain (at least not until it is authenticated) and hence cannot access the protected resource under WEB-INF. Thus putting all JSPs under the WEB-INF directly or as sub-directories if needed is the easiest and also the best way of protecting direct access to JSPs. What if the hyperlink in one of your page wants to really just forward to another JSP? Is that disallowed as well? Yeah! You cannot have different rules in your system right? However there is a way around.
Consider the case when a hyperlink in page A needs to forward request to page B. Instead of directly forwarding to page B, which is disallowed, you can put the following entry in the struts-config.xml
<action path=â€/gotoPageBâ€
parameter=â€/WEB-INF/pageB.jspâ€
type=â€org.apache.struts.actions.ForwardAction†/>
On the pageA, the hyperlink can point to “pageB.do†is
suffix mapping is used or some other path is path mapping is used. Either ways,
the ActionMapping shown above is picked up and as its type
indicates, the action is just a ForwardAction,
which as the name suggest is a forward. However since
the forward is occurring from within the container, (in the
protection domain) it is allowed.
A question might be popping up in your mind. The technique just
highlighted is the easiest and also supposedly the best. Why do I need
anything lesser than best? The answer is not all containers support the behavior just
mentioned. As we stated earlier, since the specification is clear about not
letting direct access to resources under WEB-INF, all J2EE compliant application servers
implement it. However, the second part is not stated in the specification and
consequently it is the vendor’s prerogative to implement it or not. Certain
providers do (For e.g. Tomcat) and others don’t (For e.g. WebLogic). Hence we have to
have an alternate mechanism for the less fortunate ones. This one is not
difficult either. Instead of putting the JSPs underneath WEB-INF, they can stay
wherever they
are. The following entries are added to the web.xml.
<security-constraint>
<web-resource-collection>
<web-resource-name>Deny Direct Access</web-resource-name>
<description>
Deny direct access to JSPs by associating them with denied role
</description>
<url-pattern>*.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Denied</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>Denied</role-name>
</security-role>
First, all the url patterns ending with suffix “.jsp†are associated with a Role named “Deniedâ€. Any user who wants to access the JSP pages directly should be in that role. We further ensure that no user of the system is in that Role. Role and user association is done depending on your implementation of authentication and authorization. For instance, if you are using LDAP as the user persistence mechanism, then the users, their passwords and Roles are stored in LDAP. If you ensure nobody gets the Denied role, then you have effectively prevented everyone from directly accessing the JSPs. You will still have to have the ForwardAction as shown earlier in this section if you have situation when page A needs to just navigate to page B. The internal forwards to other JSPs using RequestDispatcher are okay because the container does not intercept and cross check internal forwards even though the url-pattern matches the ones in web.xml.
NOTE: The default pagePattern and forwardPattern values for <controller> element in struts-config.xml are $M$P, where $M is replaced with the module prefix and the $P is replaced with the path attribute of the selected forward. If you place your JSP files under WEB-INF for access protection, you have to set the pagePattern and forwardPattern attributes of the <controller> element in the struts-config.xml to /WEB-INF/$M$P to tell Struts to construct the paths correctly.
Archived Comments
1. how limit for no of users for particular role to stored in ldap will be set ??
View Tutorial By: priyanka at 2014-12-16 13:39:55
2. how limit for no of users for particular role to stored in ldap will be set ??
View Tutorial By: priyanka at 2014-12-16 13:39:09
3. Great stuff .. mate
View Tutorial By: buminda at 2013-04-26 07:46:16
4. Works Just Fine...Great Tutorial!
View Tutorial By: Abhishek Alate at 2012-04-22 05:09:28
5. Great work... keep it up :)
View Tutorial By: Kushan at 2010-07-05 23:36:12
6. A good tutorial! Hope this would help the JSP developers.
View Tutorial By: geetha at 2008-09-12 04:17:14
Comment on this tutorial
- Data Science
- Android
- AJAX
- ASP.net
- C
- C++
- C#
- Cocoa
- Cloud Computing
- HTML5
- Java
- Javascript
- JSF
- JSP
- J2ME
- Java Beans
- EJB
- JDBC
- Linux
- Mac OS X
- iPhone
- MySQL
- Office 365
- Perl
- PHP
- Python
- Ruby
- VB.net
- Hibernate
- Struts
- SAP
- Trends
- Tech Reviews
- WebServices
- XML
- Certification
- Interview
categories
Related Tutorials
Configuring JDBC DataSources in Struts
When is the best time to validate input in Struts
Simple example of using the requiredif Validator rule in Struts
How to prepopulate a form in Struts
Using JavaScript to submit a form in Struts
FAQ: Why are my checkboxes not being set from ON to OFF?
FAQ: Why was reload removed from Struts (since 1.1)?
What is a Plug-in and how to use Java plug-ins with Struts?
Origin and Architecture of Struts
Handling multiple buttons in HTML Form in Struts