You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Kerry <to...@avionicengineers.com> on 2022/09/17 13:46:12 UTC

Tomcat 9 - Missing auth-constraint configuration appears to allow access to protected content

Hi all,

The origin of this question started with a Spring-Boot application which uses Tomcat by default as its web-server. For reference I originally posted a question to Stackoverflow here:

https://stackoverflow.com/questions/73339090/when-authroles-not-specified-why-is-unauthenticated-access-to-endpoints-permitte

By accident I found that if the 'keycloak.security-constraints[0].authRoles[0] were missing from the application.properties for a declared security constraint then no authorisation checks were applied to end points that match the corresponding pattern. This was unexpected as I assume if no roles were specified then it would be impossible to access the protected endpoints because there could never be a match. This would also seem sensible in-case of server misconfiguration e.g. typo in the property string, the server would default to the most secure method possible i.e. no access whatsoever.

In accordance with Servlet 4.0 specification JSR-369 (but also in Servlet 3.X) section 13.8 'Specifying Security constraints':

'An authorization constraint that names no roles indicates that access to the constrained requests must not be permitted under any circumstances'

Although I find the term 'constrained requests' a little confusing in this context I interpret this statement as agreeing with my assumption above (instead of 'constrained-requests', 'protected resources' would be an improved fit?).

On this basis I have looked into this further to see whether this is a Keycloak issue - my original Spring Boot application uses the keycloak-spring-boot-starter dependency or lies else where.

I deployed a stand-alone instance of Tomcat with the following web.xml:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
   version="4.0"
   metadata-complete="true">

   <display-name>Security Test Deployment</display-name>
   <description>
      Testing of Security constraints.
   </description>
     <security-role>
         <role-name>privileged</role-name>
     </security-role>>
     <security-constraint>
         <web-resource-collection>
             <web-resource-name>protected pages</web-resource-name>
             <url-pattern>/protected/*</url-pattern>
         </web-resource-collection>
     </security-constraint>
</web-app>

I then placed two jsp files in the root folder for the application:

1. index.jsp  - in the root folder for the application

2. protected.jsp in a sub-folder 'protected' to match the above url-pattern

I found that with this configuration I was able to access /protected/protected.jsp without any authorisation.

However I found that if I placed an empty 'auth-constraint' element in the web.xml then I could NOT access /protected/protected.jsp without authorisation. e.g include the following in web.xml:

<auth-constraint>
</auth-constraint>

In some respects this does comply with the servlet spec. because no roles were given however I would have expected if the 'auth-constraint' were missing it would be the same as it existing but with no roles specified.

Further, I also found that attempting to limit the type of http method used did not appear to work. e.g. having:

<display-name>Security Test Deployment</display-name>
<description>
      Testing of Security constraints.
</description>
<security-role>
     <role-name>privileged</role-name>
</security-role>>
<security-constraint>
     <web-resource-collection>
         <web-resource-name>protected pages</web-resource-name>
         <url-pattern>/protected/*</url-pattern>
         </web-resource-collection>
         <auth-constraint>
             <role-name>privileged</role-name>
         </auth-constraint>
         <http-method>PUT</http-method>
</security-constraint>

I anticipated an unauthorised  GET on the /protected/* url to fail but completes successfully.

I have tried the above steps on an instance of Jetty and it exhibits the same behaviour as Tomcat.  I have little direct experience of working with either Tomcat or Jetty and with Spring Boot and the Keycloak Spring Boot starter I am one step removed from the Tomcat configuration.

My concern here is that it appears quite easy to misconfigure Tomcat via the Keycloak application.properties and not be aware of unsecured end points. If this is an issue then it appears to lie within Tomcat as I can reproduce my original issue seen with a Spring Boot application in a stand-alone instance of Tomcat and a simple hand-craft application deployed to it.

Is what I am seeing expected behaviour?

Tomcat Version: 9.0.65,

Tested on: Linux Mint 20.2 cinnamon

JDK: openjdk 17.0.4 2022-07-19
OpenJDK Runtime Environment (build 17.0.4+8-Ubuntu-120.04)

Regards

Kerry



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Tomcat 9 - Missing auth-constraint configuration appears to allow access to protected content

Posted by Mark Thomas <ma...@apache.org>.
On 17/09/2022 14:46, Kerry wrote:

<snip/>

> I deployed a stand-alone instance of Tomcat with the following web.xml:
> 
> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
>    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
> http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
>    version="4.0"
>    metadata-complete="true">
> 
>    <display-name>Security Test Deployment</display-name>
>    <description>
>       Testing of Security constraints.
>    </description>
>      <security-role>
>          <role-name>privileged</role-name>
>      </security-role>>
>      <security-constraint>
>          <web-resource-collection>
>              <web-resource-name>protected pages</web-resource-name>
>              <url-pattern>/protected/*</url-pattern>
>          </web-resource-collection>
>      </security-constraint>
> </web-app>
> 
> I then placed two jsp files in the root folder for the application:
> 
> 1. index.jsp  - in the root folder for the application
> 
> 2. protected.jsp in a sub-folder 'protected' to match the above url-pattern
> 
> I found that with this configuration I was able to access 
> /protected/protected.jsp without any authorisation.

This behaviour is correct. As per section 13.8 of the Servlet specification:

"If no authorization constraint applies to a request, the container must 
accept the request without requiring user authentication."

Note: An "authorization constraint" is the "<auth-constraint>" element 
that may be nested under a "<security-constraint>" element.

> > However I found that if I placed an empty 'auth-constraint' element in 
> the web.xml then I could NOT access /protected/protected.jsp without 
> authorisation. e.g include the following in web.xml:
> 
> <auth-constraint>
> </auth-constraint>

This behaviour is correct. As per section 13.8 of the Servlet specification:

"An authorization constraint that names no roles indicates that
access to the constrained requests must not be permitted under any 
circumstances."

As you have found "No authorization constraint" != "Authorization 
constraint without any roles".

> In some respects this does comply with the servlet spec. because no 
> roles were given however I would have expected if the 'auth-constraint' 
> were missing it would be the same as it existing but with no roles 
> specified.

Your expectation is not correct. It is an understandable expectation, 
but it is not correct.

> Further, I also found that attempting to limit the type of http method 
> used did not appear to work. e.g. having:
> 
> <display-name>Security Test Deployment</display-name>
> <description>
>       Testing of Security constraints.
> </description>
> <security-role>
>      <role-name>privileged</role-name>
> </security-role>>
> <security-constraint>
>      <web-resource-collection>
>          <web-resource-name>protected pages</web-resource-name>
>          <url-pattern>/protected/*</url-pattern>
>          </web-resource-collection>
>          <auth-constraint>
>              <role-name>privileged</role-name>
>          </auth-constraint>
>          <http-method>PUT</http-method>
> </security-constraint>
> 
> I anticipated an unauthorised  GET on the /protected/* url to fail but 
> completes successfully.

This is also correct. If you specify HTTP methods as part of a 
constraint then the constraint applies ONLY to those methods.

See section 13.8.4 for more details of constraints and uncovered HTTP 
methods.

> I have tried the above steps on an instance of Jetty and it exhibits the 
> same behaviour as Tomcat.  I have little direct experience of working 
> with either Tomcat or Jetty and with Spring Boot and the Keycloak Spring 
> Boot starter I am one step removed from the Tomcat configuration.
> 
> My concern here is that it appears quite easy to misconfigure Tomcat via 
> the Keycloak application.properties and not be aware of unsecured end 
> points. If this is an issue then it appears to lie within Tomcat as I 
> can reproduce my original issue seen with a Spring Boot application in a 
> stand-alone instance of Tomcat and a simple hand-craft application 
> deployed to it.

There is no Tomcat issue here. Tomcat is behaving as required by the 
Servlet specification.

I strongly recommend reading the relevant sections of the Servlet 
specification.

> Is what I am seeing expected behaviour?

Yes.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org