Bug 337878 - Jetty security handler fails to restrict GET method when handling servlets
Summary: Jetty security handler fails to restrict GET method when handling servlets
Status: RESOLVED WORKSFORME
Alias: None
Product: Jetty
Classification: RT
Component: server (show other bugs)
Version: 7.3.0   Edit
Hardware: PC Windows 7
: P3 major (vote)
Target Milestone: 7.2.x   Edit
Assignee: David Jencks CLA
QA Contact:
URL:
Whiteboard:
Keywords: core, security
Depends on:
Blocks:
 
Reported: 2011-02-22 13:33 EST by Boris Hamanov CLA
Modified: 2011-04-08 15:07 EDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Boris Hamanov CLA 2011-02-22 13:33:52 EST
Build Identifier: jetty-7.3.0.v20110203

I have a web xml with a security descriptor like this

    <servlet-mapping>
        <servlet-name>MailerEndPointServlet</servlet-name>
        <url-pattern>/error.prati</url-pattern>
    </servlet-mapping>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>restrict everything</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint/>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>allowed servlets and methods</web-resource-name>
            <url-pattern>/error.prati</url-pattern>
            <http-method>POST</http-method>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

This URL should trigger a forbidden response from jetty

http://www.myhost.com/context/error.prati?df=dd

But it does not.

I have a context registered for my web app like this:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
.
.
.
  <!-- enable security -->
  <Get name="securityHandler">
    <Set name="loginService">
      <New class="org.eclipse.jetty.security.HashLoginService">
	    <Set name="name">Empty Realm</Set>
      </New>
    </Set>
    <Set name="checkWelcomeFiles">true</Set>
  </Get>

It actually works in my eclipse project where Jetty is used as a J2EE preview (org.mortbay.jetty.server_6.1.15.v200905151201)

Reproducible: Always

Steps to Reproduce:
1. Deploy a web application with security descriptor that restricts everything, but a POST requests
2. Configure security handler
3. Send a GET request - it goes through instead of being rejected.
Comment 1 Greg Wilkins CLA 2011-02-22 17:57:57 EST
I believe this is not an issue, but a very unfortunate side effect of the servlet specification, which says:

SRV.12.7.3 Processing Requests
When a Servlet container receives a request, it shall use the algorithm described in SRV.11.1 to select the constraints (if any) defined on the url-pattern that is the best match to the request URI. If no constraints are selected, the container shall accept the request. Otherwise the container shall determine if the HTTP method of the request is constrained at the selected pattern. If it is not, the request shall be accepted. Otherwise, the request must satisfy the constraints that apply to the http-method at the url-pattern. Both of the following rules must be satisfied for the request to be accepted and dispatched to the associated servlet.


So in your case, the URL's best match is the constraint at /error.prati and that is the constraint that is selected.   Only then is the method check and because it does not match a GET request, the request is allowed!!!  There is no allowance to fall back to the next best URL match and try that!   

I argued long and hard against this behaviour in the servlet EG, but the only result was that in servlet 3.0, they allow you to define a constraint using the http-method-omission element to catch all methods not specified in another constraint.

I think in servlet 2.5, you have no option but to specify another constraint at /error.prati that forbids the other common methods (GET, HEAD, OPTIONS etc.)

In Jetty 6 we had implemented the sane fallback approach, but in Jetty-7 we fully follow the servlet spec.
Comment 2 Greg Wilkins CLA 2011-02-22 18:04:39 EST
David,

can you confirm/deny this analysis?
Comment 3 Boris Hamanov CLA 2011-02-23 03:21:45 EST
Thanks Greg, I can see the logic of what you are saying. If the uri has priority over the method in selecting the constraint to apply, it will produce the problematic effect. The specification of security constraints is ambiguous and not well designed at all. I was under the impression that both uri and method must match for a constraint to be applied; otherwise, it falls back to the next best. I will try the workaround you mentioned and see if that helps.
Comment 4 David Jencks CLA 2011-02-24 15:37:28 EST
Greg is correct, this is working according to the spec.

While you may not like the way security constraints work, since at least servlet 2.5 the meaning has been completely unambiguous and completely specified.

I agree that this behavior of adding an additional constraint and having as a side effect that previously restricted methods are now allowed is surprising (I was certainly surprised when I found it).  I've found that after thinking this way for a while it makes sense.  After a lot of thought I haven't come up with a better way of specifying constraints.  I suspect you will find alternative approaches are more ambiguous and less clear.
Comment 5 Boris Hamanov CLA 2011-02-25 16:39:26 EST
Thanks guys!
Comment 6 Wayne Beaton CLA 2011-04-08 13:31:54 EDT
Is it time for the committer-only flag be removed from this bug?