You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Markus Jung <ma...@gmail.com> on 2011/06/14 16:00:01 UTC

CSRF protection module

Hi, 

if somebody is interested on the current status of the CSRF protection a
maven repository is now available.

Add the following settings to your Tapestry pom.xml:

<repositories>

        <repository>
			<id>csrfprotection-snapshots</id>
		
<url>https://gsoc2011-csrf-protection.googlecode.com/svn/maven/snapshot-repo</url>
	</repository>
</repositories>

<dependencies>

	<dependency>
        	<groupId>org.apache.tapestry</groupId>
        	<artifactId>csrfprotection</artifactId>
        	<version>0.1-SNAPSHOT</version>
        </dependency>
</dependencies>

The CSRF protection module is compatible with the current Tapestry
5.3.0-SNAPSHOT, so you have to switch to that version:
<properties>
        <tapestry-release-version>5.3.0-SNAPSHOT</tapestry-release-version>
</properties>

Usage:

This module provides the following artefacts:
csrfprotection/CsrfProtected mixin
@CsrfProtected annotation

The mixin can be applied on any component. In the afterRender method it
calls the insertCSRFToken method of the component. If the component does not
provide this method it is added by a ComponentClassTransformWorker that
scans all controlled packages for components. For known components an
optimized method is created for other components a generic method is created
that works with an XPath expression.

The annotation can be applied on eventHandler Methods, e.g. onSuccess() or
on Page classes. The ComponentClassTransformWorker adds a simple advice that
checks the client token against the server token. If the annotation is used
on the Page class, this check is performed with the activate event of the
Page. In this way components like BeanEditForm can be protected since the
event handling method might not be included in the page class. The protected
Page class is not required to implement the onActivate method.

If the token check fails an CsrfException is thrown.

The anti CSRF token is currently session based.

Best regards,
Markus









--
View this message in context: http://tapestry.1045711.n5.nabble.com/CSRF-protection-module-tp4487920p4487920.html
Sent from the Tapestry - Dev mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: CSRF protection module

Posted by Markus Jung <ma...@gmail.com>.
I'll shut my local server down and move the Jumpstart demo to a public
server. As soon it is up again, I'll post the link.

BR
Markus

--
View this message in context: http://tapestry.1045711.n5.nabble.com/CSRF-protection-module-tp4487920p4557674.html
Sent from the Tapestry - Dev mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: CSRF protection module

Posted by Markus Jung <ma...@gmail.com>.
There is now a showcase for the cross-site request forgery protection based
on the Jumpstart demo project available at:

http://viennamarkus.dyndns-free.com:8888/jumpstart

It uses the auto protection mode, which requires only a config entry in the
AppModule of Jumpstart. So far all different component types and interaction
can be protected. A few pages are not working properly but this is due to my
custom port of the chenillekit and of Jumpstart to Tapestry 5.3.0, but the
CSRF protection still works also there. 

I switched for the auto mode of the protection to a decorator for the
ComponentEventLinkEncoder, because the AjaxFormLoop made some troubles in
the other approach. So the auto mode works now fine also for the
AjaxFormLoop component.

The problem there is that I'm currently not able to provide a mixin for that
component - the critical code part is:

AjaxFormLoop:
 public void addRemoveRowTrigger(String clientId)
        {
            Link link = resources.createEventLink("triggerRemoveRow",
toClientValue());

            String asURI = link.toURI();

            JSONObject spec = new JSONObject();
            spec.put("link", clientId);
            spec.put("fragment", currentFragmentId());
            spec.put("url", asURI);

            jsSupport.addInitializerCall("formLoopRemoveLink", spec);
        }

Through the ComponentEventLinkEncoder approach I can add the CSRF protection
token already in the createEventLink method. But I don't know how I can
provide a insertCSRFtoken method for that component that can be called in
the afterRender phase, since the link goes into javascript and is not
represented in the markup. 

Maybe I can try to identify component instances that have the mixin attached
und build a list of client ids at startup and then in the the
ComponentEventLinkEncoder I evaluate this list to decide whether to add the 
protection token or not

I would appreciate any help for the Mixin based protection of the
AjaxFormLoop component and comments about the current solution.

BR
Markus



--
View this message in context: http://tapestry.1045711.n5.nabble.com/CSRF-protection-module-tp4487920p4553028.html
Sent from the Tapestry - Dev mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: CSRF protection module

Posted by Markus Jung <ma...@gmail.com>.
Hi, 

there is now an auto CSRF protection mode available. By including the CSRF
protection module and providing the application defaults -
configuration.add(CsrfProtectionModule.ANTI_CSRF_MODE,
CsrfProtectionModule.ANTI_CSRF_MODE_AUTO); - every Form or
AbstractComponentEventLink based component is protected, which works in my
sample app for all used components.

How it works:
-) My component class transformation adds the insertCSRFToken method to all
components
-) Furthermore the transformation adds to
org.apache.tapestry5.corelib.components.Form,
org.apache.tapestry5.corelib.base.AbstractComponentEventLink my
CsrfProtected mixin
-) The mixin calls the insertCSRFToken method in the afterRender phase
-) A ComponentEventRequestFilter checks the token 
-) A @NotCsrfProtected annotation can be used for pages that should not be
protected
-) If for any reasons the auto protection does not work in a case, the
explicit protection with the mixin and the @CsrfProtected annotation can be
used


Issues - Auto Mode:
1. Page render request: These requests are excluded from auto protection. It
would be easy to include them, but these events should not trigger any
functionality that could be exploited with CSRF.

2. The filter checks the page annotation with reflection on each call. I
will build a Service that holds a constant page list that is built upon app
start, to avoid using reflection all the time. 

Issues - Explicit Mode (Mixin + @CsrfProtected)

3. The @CsrfProtected on page level adds the token check logic as advice to
the onActivate event of the page. If there is no onActivate event I add the
advice to the dispatchComponentEvent method of the page with a check for the
onActivate event. This is a little bit of a hack. My idea was to add the
onActivate method if it is not present at the page and to let the other
workers of Tapestry do the rest. But the worker classes that handle the
onActivate logic don't use introduced methods of other workers. If they
would use it it would be a nice way to add functionality based on the
existing tapestry mechanisms. 

For now I think I will change the logic to use a
ComponentEventRequestFilter. If the @CsrfProtected annotation is present on
a page I'll check the token.

Next steps:
-) Test of the CSRF protection with the Jumpstart demo
-) Unit tests
-) Documentation page

BR,
Markus











--
View this message in context: http://tapestry.1045711.n5.nabble.com/CSRF-protection-module-tp4487920p4527453.html
Sent from the Tapestry - Dev mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org