Geronimo
  1. Geronimo
  2. GERONIMO-2695

Requests using Non-secure HTTP connections cannot access unsecured web resources

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.1.1
    • Fix Version/s: 1.1.2, 1.2, 2.0-M2
    • Component/s: security, Tomcat, web
    • Security Level: public (Regular issues)
    • Labels:
      None
    • Environment:

      Geronimo running on Windows XP

      Description

      Consider the following fragment of my web.xml in my WAR:


      <security-constraint>
      <display-name>Unsecure Constraint</display-name>
      <web-resource-collection>
      <web-resource-name>Unsecure Resource Collection</web-resource-name>
      <url-pattern>/common/error/*</url-pattern>
      <url-pattern>/common/includes/*</url-pattern>
      <url-pattern>/common/Message.jsp</url-pattern>
      <url-pattern>/common/resources/*</url-pattern>
      <url-pattern>/common/security/login.jsp</url-pattern>
      <url-pattern>/common/security/logout.jsp</url-pattern>
      <url-pattern>/servlet/branding/*</url-pattern>
      <url-pattern>/servlet/image/*</url-pattern>
      <url-pattern>/servlet/login/*</url-pattern>
      <url-pattern>/servlet/definecookie</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
      </web-resource-collection>
      <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
      </user-data-constraint>
      </security-constraint>
      <security-constraint>
      <display-name>Secure Constraint</display-name>
      <web-resource-collection>
      <web-resource-name>Secure Resource Collection</web-resource-name>
      <url-pattern>/</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint>
      <role-name>MXSYSTEM</role-name>
      </auth-constraint>
      <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
      </user-data-constraint>
      </security-constraint>
      <login-config>
      <auth-method>FORM</auth-method>
      <form-login-config>
      <form-login-page>/common/security/PreLogin.jsp</form-login-page>
      <form-error-page>/common/security/error.jsp</form-error-page>
      </form-login-config>
      </login-config>
      <security-role>
      <description>Application System Role</description>
      <role-name>MXSYSTEM</role-name>
      </security-role>


      There are two sets of web resources defined: a secured web resource collection, and an unsecured web resource collection. The secured web collection is by default everything that matches the "/" pattern. In the unsecured web collection, we use specific URL patterns so that certain resources can be accessed prior to login. Note that there is no security role defined for the unsecured web resource collection, as these resources should be available to every request.

      The problem is that access is denied to to the unsecured web resource collection, even though they are defined as unsecured. A blank HTML page is returned instead of the appropriate resource. After some debugging, I discovered what seems to be a bug in the org.apache.geronimo.tomcat.realm.TomcatGeronimoRealm class. Consider the following code fragment in the hasResourceCollection(...) method:


      // Which user principal have we already authenticated?
      Principal principal = request.getUserPrincipal();

      //If we have no principal, then we should use the default.
      if (principal == null)

      { return request.isSecure(); }

      else

      { Subject currentCaller = ((JAASTomcatPrincipal) principal).getSubject(); ContextManager.setCallers(currentCaller, currentCaller); }

      When I make an HTTP connection to an unsecure web resource, I am unauthenticated before I can login. Thus, the principal in this case is null. In the case of a null principal, the code seems to base its authorization on whether or not the request is secure! This seems very strange to me, as it should be able to accept normal, unauthenticated, HTTP connections to unsecure web resources.

      I tried accessing the unsecured web resources over HTTPS, and sure enough, I was able to access them because of the secure connection. I'm not sure why this works only over HTTPS...it should work in both cases.

      1. test.war
        2 kB
        Aman Nanner
      2. GERONIMO-2695-1.1.x.patch
        6 kB
        Vamsavardhana Reddy

        Issue Links

          Activity

          Hide
          Jeff Genender added a comment -

          Please post your geronimo-web.xml. You should have done a role/principal mapping which would effectively give you a default principal if unauthenticated. In other words, the principal would never be null.

          Show
          Jeff Genender added a comment - Please post your geronimo-web.xml. You should have done a role/principal mapping which would effectively give you a default principal if unauthenticated. In other words, the principal would never be null.
          Hide
          Aman Nanner added a comment -

          Hi,

          My web module is contained with an application module, so I defined an "empty" default principal as follows:


          <security:security>
          <security:default-principal>
          <security:principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="" />
          </security:default-principal>
          <security:role-mappings>
          <security:role role-name="MXSYSTEM">
          <security:principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="mxsystem" designated-run-as="true" />
          </security:role>
          </security:role-mappings>
          </security:security>


          I did this as I did not want my unsecured web resources to run under any principal (i.e. I wanted them to run as unauthenticated).

          Show
          Aman Nanner added a comment - Hi, My web module is contained with an application module, so I defined an "empty" default principal as follows: <security:security> <security:default-principal> <security:principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="" /> </security:default-principal> <security:role-mappings> <security:role role-name="MXSYSTEM"> <security:principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="mxsystem" designated-run-as="true" /> </security:role> </security:role-mappings> </security:security> I did this as I did not want my unsecured web resources to run under any principal (i.e. I wanted them to run as unauthenticated).
          Hide
          Jeff Genender added a comment -

          Ok...can you throw together a small war evincing this problem and post it to the JIRA and we should be able to debug and fix it. Thanks.

          Show
          Jeff Genender added a comment - Ok...can you throw together a small war evincing this problem and post it to the JIRA and we should be able to debug and fix it. Thanks.
          Hide
          Aman Nanner added a comment -

          I've attached a very simple WAR that demonstrates the issue. You'll be able to access the index.html via HTTPS, but not HTTP.

          Show
          Aman Nanner added a comment - I've attached a very simple WAR that demonstrates the issue. You'll be able to access the index.html via HTTPS, but not HTTP.
          Hide
          Jeff Genender added a comment -

          Also...I think I see a possible issue in your web.xml.

          Looking at your web.xml it appears that your security constraints are overlapping. This can cause problems. You can either make it more specific as to what is secure and what is not, or you can try changing the order of precedence (which is a shot in the dark).

          Try swapping the order of how they appear (make the unauthenticated come second). Right now your authenticated /* overrides the unauthenticated completely, and thus you really have no such thing as an unauthenticated access. Try making that one come first, then the unauthenticated becomes the exception.

          Here is a great article on this issue and provides some good background to the problem you may be encountering:

          http://www2.sys-con.com/ITSG/virtualcd/Java/archives/0704/mccay/index.html

          In particular, and which applies to my statement above:

          "Tomcat's implementation of the constraint-matching algorithm requires that the constraints appear within the deployment descriptor in the order of precedence required for the different types of URL patterns"

          Show
          Jeff Genender added a comment - Also...I think I see a possible issue in your web.xml. Looking at your web.xml it appears that your security constraints are overlapping. This can cause problems. You can either make it more specific as to what is secure and what is not, or you can try changing the order of precedence (which is a shot in the dark). Try swapping the order of how they appear (make the unauthenticated come second). Right now your authenticated /* overrides the unauthenticated completely, and thus you really have no such thing as an unauthenticated access. Try making that one come first, then the unauthenticated becomes the exception. Here is a great article on this issue and provides some good background to the problem you may be encountering: http://www2.sys-con.com/ITSG/virtualcd/Java/archives/0704/mccay/index.html In particular, and which applies to my statement above: "Tomcat's implementation of the constraint-matching algorithm requires that the constraints appear within the deployment descriptor in the order of precedence required for the different types of URL patterns"
          Hide
          Aman Nanner added a comment -

          Actually, I can omit the secured resource collection completely and I still experience the same issue. The test WAR that I included only has an unsecured resource collection and thus demonstrates this.

          Show
          Aman Nanner added a comment - Actually, I can omit the secured resource collection completely and I still experience the same issue. The test WAR that I included only has an unsecured resource collection and thus demonstrates this.
          Hide
          Jeff Genender added a comment -

          "Actually, I can omit the secured resource collection completely and I still experience the same issue. The test WAR that I included only has an unsecured resource collection and thus demonstrates this."

          Yep and this is my point. I believe your web.xml is wrong. Here is the changes to the web.xml you put in your example and it works absolutely fine for me:

          <?xml version="1.0" encoding="UTF-8"?>
          <web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4">
          <display-name>Test Web Application</display-name>
          <security-constraint>
          <display-name>Secure Constraint</display-name>
          <web-resource-collection>
          <web-resource-name>Secure Resource Collection</web-resource-name>
          <url-pattern>/</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
          </web-resource-collection>
          <auth-constraint>
          <role-name>MXSYSTEM</role-name>
          </auth-constraint>
          <user-data-constraint>
          <transport-guarantee>NONE</transport-guarantee>
          </user-data-constraint>
          </security-constraint>
          <security-constraint>
          <display-name>Unsecure Constraint</display-name>
          <web-resource-collection>
          <web-resource-name>Unsecure Resource Collection</web-resource-name>
          <url-pattern>/index.html</url-pattern>
          <url-pattern>/login.html</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
          </web-resource-collection>
          <auth-constraint>
          <role-name>*</role-name>
          </auth-constraint>
          <user-data-constraint>
          <transport-guarantee>NONE</transport-guarantee>
          </user-data-constraint>
          </security-constraint>
          <login-config>
          <auth-method>FORM</auth-method>
          <form-login-config>
          <form-login-page>/login.html</form-login-page>
          <form-error-page>/login.html</form-error-page>
          </form-login-config>
          </login-config>
          <security-role>
          <description>Maintenix Application System Role</description>
          <role-name>MXSYSTEM</role-name>
          </security-role>
          </web-app>

          Show
          Jeff Genender added a comment - "Actually, I can omit the secured resource collection completely and I still experience the same issue. The test WAR that I included only has an unsecured resource collection and thus demonstrates this." Yep and this is my point. I believe your web.xml is wrong. Here is the changes to the web.xml you put in your example and it works absolutely fine for me: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"> <display-name>Test Web Application</display-name> <security-constraint> <display-name>Secure Constraint</display-name> <web-resource-collection> <web-resource-name>Secure Resource Collection</web-resource-name> <url-pattern>/</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>MXSYSTEM</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <display-name>Unsecure Constraint</display-name> <web-resource-collection> <web-resource-name>Unsecure Resource Collection</web-resource-name> <url-pattern>/index.html</url-pattern> <url-pattern>/login.html</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.html</form-login-page> <form-error-page>/login.html</form-error-page> </form-login-config> </login-config> <security-role> <description>Maintenix Application System Role</description> <role-name>MXSYSTEM</role-name> </security-role> </web-app>
          Hide
          Jeff Genender added a comment -

          Oh to be more poignant...I can make your test.war work by adding the following to your constraint:

          <auth-constraint>
          <role-name>*</role-name>
          </auth-constraint>

          Show
          Jeff Genender added a comment - Oh to be more poignant...I can make your test.war work by adding the following to your constraint: <auth-constraint> <role-name>*</role-name> </auth-constraint>
          Hide
          Aman Nanner added a comment -

          Hmm...I'll test this out in a bit.

          I was under the impression that


          <auth-constraint>
          <role-name>*</role-name>
          </auth-constraint>

          implies that all AUTHENTICATED users of any role are allowed to access the given resource. I know that failure to specify an authorization constraint implies unrestricted access for JBoss, WebLogic, and Jetty. Perhaps this is an area of subjective interpretation of the Servlet 2.4 spec.

          In this case, is it possible to modify the interpretation such that the absence of an <auth-constraint> tag implies the above XML fragment, such that these web applications can port over to Geronimo more easily?

          Thanks

          Show
          Aman Nanner added a comment - Hmm...I'll test this out in a bit. I was under the impression that <auth-constraint> <role-name>*</role-name> </auth-constraint> — implies that all AUTHENTICATED users of any role are allowed to access the given resource. I know that failure to specify an authorization constraint implies unrestricted access for JBoss, WebLogic, and Jetty. Perhaps this is an area of subjective interpretation of the Servlet 2.4 spec. In this case, is it possible to modify the interpretation such that the absence of an <auth-constraint> tag implies the above XML fragment, such that these web applications can port over to Geronimo more easily? Thanks
          Hide
          Jeff Genender added a comment -

          We let Tomcat do the deployment so this is a Tomcat thing. Are you saying this works in JBoss? I understand they use the Tomcat deployer too. If you are saying that the war file you attached works fine in JBoss but not in Geronimo, then we need to dig deeper because that part of the deployment is being implemented purely by Tomcat on both platforms and they should operate the same. If not, then you have likely found a bug, and we need to investigate the TomcatGeronimoRealm a bit more deeply.

          Show
          Jeff Genender added a comment - We let Tomcat do the deployment so this is a Tomcat thing. Are you saying this works in JBoss? I understand they use the Tomcat deployer too. If you are saying that the war file you attached works fine in JBoss but not in Geronimo, then we need to dig deeper because that part of the deployment is being implemented purely by Tomcat on both platforms and they should operate the same. If not, then you have likely found a bug, and we need to investigate the TomcatGeronimoRealm a bit more deeply.
          Hide
          Jeff Genender added a comment -

          Ok...this was pointed out to me that we do process the security attributes...and thus I do believe this is a bug. I'll take a swipe at it.

          Show
          Jeff Genender added a comment - Ok...this was pointed out to me that we do process the security attributes...and thus I do believe this is a bug. I'll take a swipe at it.
          Hide
          Aman Nanner added a comment -

          Yes, this does work on JBoss, and you are correct in your last comment that Geronimo processes the security attributes. On each HTTP request to the server, a call is made to TomcatGeronimoRealm.hasResourcePermission(...) to check if the resource is authorized for the user. I'm pretty sure the issue has to do with the code fragment that I pointed out originally.

          Show
          Aman Nanner added a comment - Yes, this does work on JBoss, and you are correct in your last comment that Geronimo processes the security attributes. On each HTTP request to the server, a call is made to TomcatGeronimoRealm.hasResourcePermission(...) to check if the resource is authorized for the user. I'm pretty sure the issue has to do with the code fragment that I pointed out originally.
          Hide
          Jeff Genender added a comment -

          "On each HTTP request to the server, a call is made to TomcatGeronimoRealm.hasResourcePermission(...) to check if the resource is authorized for the user. I'm pretty sure the issue has to do with the code fragment that I pointed out originally."

          That wasn't my reference...since I indeed wrote that code. I was referring to the deployment code, which really is the issue here. You pointed that out via not needing the auth-constraint. That is a deployment problem, not a realm issue.

          Show
          Jeff Genender added a comment - "On each HTTP request to the server, a call is made to TomcatGeronimoRealm.hasResourcePermission(...) to check if the resource is authorized for the user. I'm pretty sure the issue has to do with the code fragment that I pointed out originally." That wasn't my reference...since I indeed wrote that code. I was referring to the deployment code, which really is the issue here. You pointed that out via not needing the auth-constraint. That is a deployment problem, not a realm issue.
          Hide
          Aman Nanner added a comment -

          Ok, I see what you mean. I tried debugging with the "*" auth-constraint, and I noticed that the TomcatGeronimoRealm.hasResourcePermission(...) method is no longer called on that request to check for authorization.

          Show
          Aman Nanner added a comment - Ok, I see what you mean. I tried debugging with the "*" auth-constraint, and I noticed that the TomcatGeronimoRealm.hasResourcePermission(...) method is no longer called on that request to check for authorization.
          Hide
          Aman Nanner added a comment -

          "Yep and this is my point. I believe your web.xml is wrong. Here is the changes to the web.xml you put in your example and it works absolutely fine for me:"

          Hi,

          I just tried the test case again with the modification to web.xml by adding:


          <auth-constraint>
          <role-name>*</role-name>
          </auth-constraint>

          and it in fact restricts access to the index.html. I think what you saw instead was the login.html page, which has the same red background as index.html, except that it says "Login Page" at the top. So this authorization constraint is in fact restricting access to the resource to all authenticated roles, and denying access to authenticated requests by redirecting to the login page.

          So this is not simulating the same behaviour as the absence of the <auth-constraint> tag.

          Show
          Aman Nanner added a comment - "Yep and this is my point. I believe your web.xml is wrong. Here is the changes to the web.xml you put in your example and it works absolutely fine for me:" Hi, I just tried the test case again with the modification to web.xml by adding: — <auth-constraint> <role-name>*</role-name> </auth-constraint> — and it in fact restricts access to the index.html. I think what you saw instead was the login.html page, which has the same red background as index.html, except that it says "Login Page" at the top. So this authorization constraint is in fact restricting access to the resource to all authenticated roles, and denying access to authenticated requests by redirecting to the login page. So this is not simulating the same behaviour as the absence of the <auth-constraint> tag.
          Hide
          Jeff Genender added a comment -

          I have a fix...and am testing now...

          The problem is the TomcatGeronimoRealm need access to the defaultPrincipal and it doesn't have it. I have made some updates and it looks like its working. After a bit more testing I will commit.

          Show
          Jeff Genender added a comment - I have a fix...and am testing now... The problem is the TomcatGeronimoRealm need access to the defaultPrincipal and it doesn't have it. I have made some updates and it looks like its working. After a bit more testing I will commit.
          Hide
          Jeff Genender added a comment -

          Ok I fixed it in 1.2 BRANCH and in 2.0 Trunk. Please try it and let me know if its fixed (unfortunately you need to build Geronimo). I recommend trying 1.2 since 2.0 is in a state of flux at the moment.

          Show
          Jeff Genender added a comment - Ok I fixed it in 1.2 BRANCH and in 2.0 Trunk. Please try it and let me know if its fixed (unfortunately you need to build Geronimo). I recommend trying 1.2 since 2.0 is in a state of flux at the moment.
          Hide
          Vamsavardhana Reddy added a comment -

          GERONIMO-2695-1.1.x.patch:

          Jeff, I have verified on branches\1,2 that your fix addressed the dup GERONIMO-2339. I have back-ported the fix to branches\1.1 and verified GERONIMO-2339. Can you commit the fix to branches\1.1? I have created GERONIMO-2695-1.1.x.patch for you to make it simpler.

          Show
          Vamsavardhana Reddy added a comment - GERONIMO-2695 -1.1.x.patch: Jeff, I have verified on branches\1,2 that your fix addressed the dup GERONIMO-2339 . I have back-ported the fix to branches\1.1 and verified GERONIMO-2339 . Can you commit the fix to branches\1.1? I have created GERONIMO-2695 -1.1.x.patch for you to make it simpler.
          Hide
          Jeff Genender added a comment -

          Vamsi, the patch looks great. If you want to apply/commit it please feel free, and since you have been kind enough to test all the versions, feel free to close this out if you think I have fixed the problem. I would commit the patch, but my maven 1 environment has not been working very well lately...so if you could do it, that would be great. Thanks!

          Show
          Jeff Genender added a comment - Vamsi, the patch looks great. If you want to apply/commit it please feel free, and since you have been kind enough to test all the versions, feel free to close this out if you think I have fixed the problem. I would commit the patch, but my maven 1 environment has not been working very well lately...so if you could do it, that would be great. Thanks!
          Hide
          Vamsavardhana Reddy added a comment -

          Fixed in rev 494061 in branches\1.1.

          Verified that the fix in branches\1.1, branches\1.2.

          Show
          Vamsavardhana Reddy added a comment - Fixed in rev 494061 in branches\1.1. Verified that the fix in branches\1.1, branches\1.2.
          Hide
          David Jencks added a comment -

          Just to clarify a couple issues that may have gotten muddied in discussion of this issue:

          1. in a security constraint, including
          <auth-constraint>
          <role-name>*</role-name>
          </auth-constraint>

          means something completely different from having no auth-constraint element. No auth-constraint element means the resources can be accessed by anyone without identifying themselves or logging in in any way. The auth-constraint with <role-name>*</role-name> means you have to log in and identify yourself successfully to the system, but then no matter what role you may have you can access the resource. (Of course this also assumes that you have been assigned to at least one role meaningful to this application, so there are still ways you could be prevented from accessing the resource

          2. The meaning of a set of security-constraint elements is completely independent of their order. Any implementation that produces different results depending on the order of security-constraint elements in a dd is wrong and does not follow the spec.

          3. Its completely acceptable if not normal to have overlapping security constraints.

          Note that the article Jeff referred to is for pre-j2ee 1.4 app servers and the 1.4 spec provided considerable clarification and definition of the meaning of the security constraint elements. I would not rely on that article as a guide to any current software. Converting security-constraint elements into a set of permissions is rather complicated but the description in the jacc 1.1 spec section 3.1.3.1 appears to be complete and about as straightforward as any description is likely to be.

          Show
          David Jencks added a comment - Just to clarify a couple issues that may have gotten muddied in discussion of this issue: 1. in a security constraint, including <auth-constraint> <role-name>*</role-name> </auth-constraint> means something completely different from having no auth-constraint element. No auth-constraint element means the resources can be accessed by anyone without identifying themselves or logging in in any way. The auth-constraint with <role-name>*</role-name> means you have to log in and identify yourself successfully to the system, but then no matter what role you may have you can access the resource. (Of course this also assumes that you have been assigned to at least one role meaningful to this application, so there are still ways you could be prevented from accessing the resource 2. The meaning of a set of security-constraint elements is completely independent of their order. Any implementation that produces different results depending on the order of security-constraint elements in a dd is wrong and does not follow the spec. 3. Its completely acceptable if not normal to have overlapping security constraints. Note that the article Jeff referred to is for pre-j2ee 1.4 app servers and the 1.4 spec provided considerable clarification and definition of the meaning of the security constraint elements. I would not rely on that article as a guide to any current software. Converting security-constraint elements into a set of permissions is rather complicated but the description in the jacc 1.1 spec section 3.1.3.1 appears to be complete and about as straightforward as any description is likely to be.

            People

            • Assignee:
              Jeff Genender
              Reporter:
              Aman Nanner
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development