View declared in <protected-views> still accessible after manipulating CSRF token

前提是你 提交于 2020-06-25 13:38:28

问题


I'm exploring the new features in JSF 2.2 (pretty cool so far) but I still don't understand how Protected Views works, I created a facelet1 with a link to facelet2, like this:

<h:link styleClass="link" value="Go to protected page" id="link1"
    outcome="/protected/facelet2.xhtml"></h:link>

and in my faces-config.xml I added this:

<protected-views>
    <url-pattern>/protected/facelet2.xhtml</url-pattern>
</protected-views>

Now when I run the page a token is added in the url:

http://localhost:8080/<project>/protected/facelet2.faces?javax.faces.Token=1426608965211

According to the documentation, if the token does not match with the one in the server, the GET request is not processed (is my understanding correct?).

But if I modify the token (using Firebug or the dev tools included in the browser) the request is still processed, even if the token was modified.

Am I doing something wrong?


回答1:


This is caused because your FacesServlet is apparently mapped on JSF 1.0-style URL pattern of *.faces instead of JSF 2.0-style URL pattern of *.xhtml. The <protected-views><url-pattern> must match the actual URL pattern as you see in browser's address bar.

So, given an actual URL of /protected/facelet2.faces, you need to configure it as below:

<protected-views>
    <url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>

However, while at it, I discovered some nasty issues in current Mojarra 2.2.10 implementation:

  1. It does actually not do a prefix/suffix match as per Servlet 12.1 specification (there's even a vague comment in source code indicating that!). It does merely an exact match. This means, you can't use wildcard URL patterns like /protected/*.

  2. When generating the <h:link>, it does not compare the protected view URL pattern to the resolved URL, but to the JSF view ID. And, when checking an incoming request, it does not compare the request URL to the JSF view ID (like as during link generation), but to the <url-pattern>. This thus never matches, totally explaining why you could simply access it without a valid token.

Basically, you need the following configuration if you need to keep the JSF 1.0-style URL pattern of *.faces.

<protected-views>
    <url-pattern>/protected/facelet2.xhtml</url-pattern>
    <url-pattern>/protected/facelet2.faces</url-pattern>
</protected-views>

It'll then properly throw javax.faces.application.ProtectedViewException when being accessed without a valid token. Much better is to just map the FacesServlet explicitly on *.xhtml in web.xml.

<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

This way you never need to deal with virtual URLs.

I've reported this to Mojarra guys as issue 3837.

See also:

  • Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?


来源:https://stackoverflow.com/questions/29104597/view-declared-in-protected-views-still-accessible-after-manipulating-csrf-toke

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!