I am using Liferay 6.2-ce-ga3, primefaces 6 and JSF2.1. I have enabled CSRF protection for my portlet adding the follow code in liferay portal-ext.properties and portlet portal-ext.properties:
auth.token.check.enabled=true
auth.token.impl=com.liferay.portal.security.auth.SessionAuthToken
futhermore, I've added in portlet.xml
<init-param>
<name>check-auth-token</name>
<value>true</value>
</init-param>
For test, I removed p_auth=<code> from my form url then I submitted the form and it's worked. That's not good, I't should not allow the request without the token.
did I forget add a filter in configuration?
how liferay check the p_auth?
should I check manually p_auth token in my bean like this tutorial?
Liferay's p_auth token protects against CSRF during the ACTION_PHASE of the portlet lifecycle. I believe that it is enabled by default in Liferay 6.2, so you shouldn't need to configure anything for it.
The p_auth token must be present for a form to submit without error during the ACTION_PHASE. However, the p_auth parameter has no effect during the RESOURCE_PHASE which is the phase where JSF Ajax form submissions are executed. So you may be dealing with a JSF Ajax request. Thankfully, JSF also has its own CSRF protection enabled by default in the view state. So you are safe from CSRF with both Ajax and non-Ajax form submissions when you use Liferay Faces.
If you confirm that p_auth has no effect during a non-Ajax form submission, there may be a security vulnerability (or an issue with your configuration). You should update to the latest version of Liferay Portal* and retest. If you are still having issues, report a secure issue: https://issues.liferay.com/secure/CreateIssue.jspa?pid=10952&issuetype=1.
*Liferay Portal 6.2 GA6 is the latest in the 6.2 line, and Liferay Portal 7.0 GA7 is the latest CE release overall. Of course there are EE releases that may have more bug fixes as well.
Related
I been working in a project with JSF 2.2 and a requeriment is to pass the Acunetix vulnerabilities validation.
I active protected-views (https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/JSF-CSRF-Demo/JSF2.2CsrfDemo.html) but still the validator says that the site isnt protected for CSRF attacks.
In the documentation says that I need a input hidden for POST request, but in JSF 2.2 says that with protected-views activated its Ok.
Do you know how to solve this problem? Do you have an implementation to solve this?
Since Mojarra/JSF 2.2. it is not possible anymore to provide a custom FaceletFactory using a web.xml context parameter:
<context-param>
<param-name>com.sun.faces.faceletFactory</param-name>
<param-value>my.faces.overrides.MyFaceletFactory</param-value>
</context-param>
My application provides some CMS features, including virtual host support to serve different pages (facelets) based on the currently requested domain. So http://www.domain1.com/index.xhtml returns different content than http://www.otherdomain.com/index.xhtml. The mechanics behind that are not that big of a deal using a custom resource resolver. The real problem when doing that is, that jsf caches the facelets only based on its requested uri, which does not contain the host name ("/index.xhtml" in both cases). I worked around this issue by simply adding the host name to it in my custom FaceletFactory: uri = "/" + getCleanHostName() + "://" + uri;. With JSF 2.2, this does not seem possible anymore. Is there any other way to archive the correct caching behavior in JSF 2.2? Disabling the faces cache is not an option due to its performance impact.
There were plans to standardize it in the JSF spec as per issue 611. However, it was cancelled later, because there were abstraction leaks. See also the What's new in JSF 2.2? But the original state was not rolled back anymore in spite of the request of Ed in issue 611 as cited below:
But when I removed the standardized FaceletFactory, in r11053, I didn't
put back the context param. Would you be satisfied if I just put it back and it worked as in 2.1?
You may want to create a new issue to wake up this.
The alternative is to replace it it by a custom ResourceHandler (not ResourceResolver, as that's deprecated in JSF 2.2), along with a custom FaceletCacheFactory (standardized since JSF 2.1) which can be registered via <factory><facelet-cache-factory> in faces-config.xml.
I need to add CSRF token (p_auth) to my Liferay (ver.6.1.1) portal project.
Liferay provides this ability out of the box with auth.token.check.enabled=true
But it does this only for requests marked with #ActionMapping annotation [source]. At that time, as I need CSRF protection for #ResourceMapping because I have a lot of ajax requests for form submitting.
Thank you for the advice.
You can find the way for implementation of protection in http://www.liferay.com/community/forums/-/message_boards/message/26782849
CSRF protection for a JSF based web app and Tomcat6 backend without using any external packages.
Kindly help.
JSF has already builtin protection against CSRF by the javax.faces.ViewState hidden field which is to be linked with the state of the component tree in the server side. If this hidden field is missing or contains a wrong value, then JSF simply won't process the POST request. On JSF 1.x the key is only a bit too easy to guess, see also JSF impl issue 812 and JSF spec issue 869. This is fixed in JSF 2.1.
Your major concern should be XSS. A succesful XSS attack can form a source for a guaranteed-to-be-succesful CSRF attack. To avoid XSS, ensure that you don't redisplay user-controlled input with <h:outputText escape="false" />. Other than that, JSF will already by default escape HTML entities.
I've been a little puzzled with this as I have not seen many examples that gave me the complete picture. The best explanation I found so far is this.
By defining a security role in web.xml such as "admin" for example, and having my login form with all the necessary fields (i.e j_security_check as action, and fields j_username, j_password), how/where does the actual authentication occur?
I plan to use a custom authentication using username/passwords (hashes) stored in the database. When the user submits the form, how do I make the Java EE Web Container invoke my sevlet/bean method do perform the actual authentication? I didn't notice any place to add a hook to my code in web.xml which would do the actual authentication.
By defining a security role in web.xml such as "admin" for example, and having my login form with all the necessary fields (i.e j_security_check as action, and fields j_username, j_password), how/where does the actual authentication occur?
In the servlet implementation, the servletcontainer. In Tomcat for example, it's done by the AuthenticatorBase class (source code here).
I plan to use a custom authentication using username/passwords (hashes) stored in the database. When the user submits the form, how do I make the Java EE Web Container invoke my sevlet/bean method do perform the actual authentication? I didn't notice any place to add a hook to my code in web.xml which would do the actual authentication.
If you'd like to keep using container managed authentication, but instead want to check the login against a database, then you need to configure the so-called "realm" accordingly. It's unclear which servletcontainer you're using, but in for example Tomcat, the documentation is available here: Tomcat 6.0 Realm HOW-TO.
If you really want to have your own homegrown authentication system invoked instead, then you need to drop the container managed security and homegrow it further. Which is not recommended.
The actual authentication is doing via either two ways:
Via a Server Proprietary way, e.g. the *LoginModules in JBoss, or the Tomcat one BalusC mentioned. These are different for each Server.
Via JASPIC, which was introduced in Java EE 6.
JASPIC pretty much has standardized the proprietary methods, but it's a fairly low-level API and unfortunately only available for full profile Java EE 6 and 7 implementations.
See Implementing container authentication in Java EE with JASPIC for more details.