You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@chemistry.apache.org by Emrul Islam <em...@emrul.com> on 2016/08/16 23:46:53 UTC

Security related question

Whilst working on a CMIS server implementation I happened to be
examining the CmisBrowserBindingServlet class and noticed that for
HTTP POST requests POSTHttpServletRequestWrapper is instantiated
before any authentication checks are carried out (e.g. before
getCallContextHandler() is invoked where a TokenHandler can check the
request).

POSTHttpServletRequestWrapper appears to process multi-part requests
as soon as it is created, getting an output stream to store data.

Unless I am mistaken (and forgive me if I am), it is conceivable that
this approach is vulnerable to Denial of Service attacks: you can send
a bunch of POST requests with multi-part data to the server that will
cause it to allocate memory (if less than memory threshold) and or
temp file space (if greater than memory threshold) and exhaust system
resources.

I would suggest that authentication should be checked before
processing multi-part requests in keeping with best practices (e.g.
rejecting unauthenticated requests as soon as possible).

Re: Security related question

Posted by Florian Müller <fm...@apache.org>.
Hi,

I've added some more code and comments around authentication.
Among other things, I added two CallContextHandlers that support 
UserPrincipals and simplify the use of custom authentication filters. I 
also made the CallContextHandler work for WebServices. That is, all 
bindings can now use the same authentication methods.


- Florian


> Hi Jay,
> 
> Yes - absolutely happy to do that.  I'll wait until I have verified my
> work-around more thoroughly but should be able to provide a 
> documentation
> update over the weekend.
> 
> Thanks
> 
> On Thu, Aug 18, 2016 at 8:50 PM, Jay Brown <ja...@us.ibm.com> 
> wrote:
> 
>> Emrul,
>> 
>> Thank you for the feedback.  Since you are knee-deep in this right 
>> now,
>> would you consider writing up a paragraph or so (with code snippets, 
>> if
>> needed) to describe your (verified) work-around while it is still 
>> fresh in
>> your mind?
>> 
>> If so, Florian and I can add it to the server development guide :
>> https://github.com/cmisdocs/ServerDevelopmentGuideV2/blob/
>> master/docs/OpenCMIS%20Server%20Development%20Guide%20-%
>> 202nd%20Edition.pdf?raw=true
>> 
>> 
>> 
>> Jay Brown
>> Senior Engineer, ECM Development
>> IBM Software Group
>> 
>> [image: Inactive hide details for Emrul Islam ---08/18/2016 08:30:50
>> AM---Hi Florian I understand the considerations here and accept 
>> th]Emrul
>> Islam ---08/18/2016 08:30:50 AM---Hi Florian I understand the
>> considerations here and accept that most usages will
>> 
>> From: Emrul Islam <em...@emrul.com>
>> To: dev@chemistry.apache.org
>> Date: 08/18/2016 08:30 AM
>> Subject: Re: Security related question
>> ------------------------------
>> 
>> 
>> 
>> Hi Florian
>> 
>> I understand the considerations here and accept that most usages will
>> see a servlet filter to carry out authentication.  I still think a
>> documentation comment or similar would be really helpful because it is
>> an implementation detail that is not easily apparent - please consider
>> that as a suggestion.
>> 
>> For my use case its easy enough for me to patch my version of OpenCMIS
>> and move the token handling code earlier in the request processing
>> (which I can do because I don't need to read the body).  I also agree
>> that servlet filters are typically where this is done but it isn't an
>> option in my case since Servlet 3 Asynchronous processing doesn't play
>> well with servlet filters on all app servers - but that's unrelated to
>> the Chemistry project.
>> 
>> Thanks for your speedy reply!
>> 
>> 
>> 
>> On Wed, Aug 17, 2016 at 4:30 PM, Florian M�ller <fm...@apache.org> 
>> wrote:
>> > Hi,
>> >
>> > You are right - with a few exceptions. ;-)
>> >
>> > In many (most?) environments the CMIS server is embedded into a DMS
>> system
>> > or an application server or a cloud infrastructure or something similar,
>> > which does the authentication check before the request actually reaches
>> the
>> > CMIS implementation. For a standalone CMIS server a Servlet filter is the
>> > preferred approach.
>> > There are many different authentication approaches; standard and
>> proprietary
>> > approaches. If you can do the authentication by looking the request HTTP
>> > headers or checking a SSL client certificate, you should do that before
>> the
>> > request hits OpenCMIS. That is, an unauthenticated request is rejected
>> early
>> > and the request body is not read. But there are a few authentication
>> methods
>> > and authentication rules that require reading the request body first,
>> > because the authentication information is in the body. For example, if
>> the
>> > UsernameToken authentication is used in the Web Service binding the user
>> > name and password are in the body. A proprietary authentication method
>> might
>> > check for a custom parameter that contains an additional secret or an
>> > application identifier or something similar.
>> > The body cannot be read twice. If you read the body in a filter, you
>> break
>> > at least all CMIS calls that accept content. OpenCMIS has to read the
>> body.
>> > To allow those authentication methods that require data from the body,
>> > OpenCMIS provides multiple places where those checks can be done with
>> full
>> > access to the body. In this case you are right. Reading and managing the
>> > body consumes resources, which will be lost if the authentication is
>> > rejected. OpenCMIS makes sure that a malicious client cannot send an
>> > infinite stream of data, but if your resources are smaller than the
>> built-in
>> > OpenCMIS limits you are in trouble. In the end it's up to the developers
>> and
>> > operators if that is acceptable or not. I wouldn't do it.
>> >
>> >
>> > - Florian
>> >
>> >
>> >
>> >> Whilst working on a CMIS server implementation I happened to be
>> >> examining the CmisBrowserBindingServlet class and noticed that for
>> >> HTTP POST requests POSTHttpServletRequestWrapper is instantiated
>> >> before any authentication checks are carried out (e.g. before
>> >> getCallContextHandler() is invoked where a TokenHandler can check the
>> >> request).
>> >>
>> >> POSTHttpServletRequestWrapper appears to process multi-part requests
>> >> as soon as it is created, getting an output stream to store data.
>> >>
>> >> Unless I am mistaken (and forgive me if I am), it is conceivable that
>> >> this approach is vulnerable to Denial of Service attacks: you can send
>> >> a bunch of POST requests with multi-part data to the server that will
>> >> cause it to allocate memory (if less than memory threshold) and or
>> >> temp file space (if greater than memory threshold) and exhaust system
>> >> resources.
>> >>
>> >> I would suggest that authentication should be checked before
>> >> processing multi-part requests in keeping with best practices (e.g.
>> >> rejecting unauthenticated requests as soon as possible).
>> 
>> 
>> 
>> 
>> 

Re: Security related question

Posted by Emrul Islam <em...@emrul.com>.
Hi Jay,

Yes - absolutely happy to do that.  I'll wait until I have verified my
work-around more thoroughly but should be able to provide a documentation
update over the weekend.

Thanks

On Thu, Aug 18, 2016 at 8:50 PM, Jay Brown <ja...@us.ibm.com> wrote:

> Emrul,
>
> Thank you for the feedback.  Since you are knee-deep in this right now,
> would you consider writing up a paragraph or so (with code snippets, if
> needed) to describe your (verified) work-around while it is still fresh in
> your mind?
>
> If so, Florian and I can add it to the server development guide :
> https://github.com/cmisdocs/ServerDevelopmentGuideV2/blob/
> master/docs/OpenCMIS%20Server%20Development%20Guide%20-%
> 202nd%20Edition.pdf?raw=true
>
>
>
> Jay Brown
> Senior Engineer, ECM Development
> IBM Software Group
>
> [image: Inactive hide details for Emrul Islam ---08/18/2016 08:30:50
> AM---Hi Florian I understand the considerations here and accept th]Emrul
> Islam ---08/18/2016 08:30:50 AM---Hi Florian I understand the
> considerations here and accept that most usages will
>
> From: Emrul Islam <em...@emrul.com>
> To: dev@chemistry.apache.org
> Date: 08/18/2016 08:30 AM
> Subject: Re: Security related question
> ------------------------------
>
>
>
> Hi Florian
>
> I understand the considerations here and accept that most usages will
> see a servlet filter to carry out authentication.  I still think a
> documentation comment or similar would be really helpful because it is
> an implementation detail that is not easily apparent - please consider
> that as a suggestion.
>
> For my use case its easy enough for me to patch my version of OpenCMIS
> and move the token handling code earlier in the request processing
> (which I can do because I don't need to read the body).  I also agree
> that servlet filters are typically where this is done but it isn't an
> option in my case since Servlet 3 Asynchronous processing doesn't play
> well with servlet filters on all app servers - but that's unrelated to
> the Chemistry project.
>
> Thanks for your speedy reply!
>
>
>
> On Wed, Aug 17, 2016 at 4:30 PM, Florian Müller <fm...@apache.org> wrote:
> > Hi,
> >
> > You are right - with a few exceptions. ;-)
> >
> > In many (most?) environments the CMIS server is embedded into a DMS
> system
> > or an application server or a cloud infrastructure or something similar,
> > which does the authentication check before the request actually reaches
> the
> > CMIS implementation. For a standalone CMIS server a Servlet filter is the
> > preferred approach.
> > There are many different authentication approaches; standard and
> proprietary
> > approaches. If you can do the authentication by looking the request HTTP
> > headers or checking a SSL client certificate, you should do that before
> the
> > request hits OpenCMIS. That is, an unauthenticated request is rejected
> early
> > and the request body is not read. But there are a few authentication
> methods
> > and authentication rules that require reading the request body first,
> > because the authentication information is in the body. For example, if
> the
> > UsernameToken authentication is used in the Web Service binding the user
> > name and password are in the body. A proprietary authentication method
> might
> > check for a custom parameter that contains an additional secret or an
> > application identifier or something similar.
> > The body cannot be read twice. If you read the body in a filter, you
> break
> > at least all CMIS calls that accept content. OpenCMIS has to read the
> body.
> > To allow those authentication methods that require data from the body,
> > OpenCMIS provides multiple places where those checks can be done with
> full
> > access to the body. In this case you are right. Reading and managing the
> > body consumes resources, which will be lost if the authentication is
> > rejected. OpenCMIS makes sure that a malicious client cannot send an
> > infinite stream of data, but if your resources are smaller than the
> built-in
> > OpenCMIS limits you are in trouble. In the end it's up to the developers
> and
> > operators if that is acceptable or not. I wouldn't do it.
> >
> >
> > - Florian
> >
> >
> >
> >> Whilst working on a CMIS server implementation I happened to be
> >> examining the CmisBrowserBindingServlet class and noticed that for
> >> HTTP POST requests POSTHttpServletRequestWrapper is instantiated
> >> before any authentication checks are carried out (e.g. before
> >> getCallContextHandler() is invoked where a TokenHandler can check the
> >> request).
> >>
> >> POSTHttpServletRequestWrapper appears to process multi-part requests
> >> as soon as it is created, getting an output stream to store data.
> >>
> >> Unless I am mistaken (and forgive me if I am), it is conceivable that
> >> this approach is vulnerable to Denial of Service attacks: you can send
> >> a bunch of POST requests with multi-part data to the server that will
> >> cause it to allocate memory (if less than memory threshold) and or
> >> temp file space (if greater than memory threshold) and exhaust system
> >> resources.
> >>
> >> I would suggest that authentication should be checked before
> >> processing multi-part requests in keeping with best practices (e.g.
> >> rejecting unauthenticated requests as soon as possible).
>
>
>
>
>

Re: Security related question

Posted by Jay Brown <ja...@us.ibm.com>.
Emrul,

Thank you for the feedback.  Since you are knee-deep in this right now,
would you consider writing up a paragraph or so (with code snippets, if
needed) to describe your (verified) work-around while it is still fresh in
your mind?

If so, Florian and I can add it to the server development guide :
https://github.com/cmisdocs/ServerDevelopmentGuideV2/blob/master/docs/OpenCMIS%20Server%20Development%20Guide%20-%202nd%20Edition.pdf?raw=true



Jay Brown
Senior Engineer, ECM Development
IBM Software Group



From:	Emrul Islam <em...@emrul.com>
To:	dev@chemistry.apache.org
Date:	08/18/2016 08:30 AM
Subject:	Re: Security related question



Hi Florian

I understand the considerations here and accept that most usages will
see a servlet filter to carry out authentication.  I still think a
documentation comment or similar would be really helpful because it is
an implementation detail that is not easily apparent - please consider
that as a suggestion.

For my use case its easy enough for me to patch my version of OpenCMIS
and move the token handling code earlier in the request processing
(which I can do because I don't need to read the body).  I also agree
that servlet filters are typically where this is done but it isn't an
option in my case since Servlet 3 Asynchronous processing doesn't play
well with servlet filters on all app servers - but that's unrelated to
the Chemistry project.

Thanks for your speedy reply!



On Wed, Aug 17, 2016 at 4:30 PM, Florian Müller <fm...@apache.org> wrote:
> Hi,
>
> You are right - with a few exceptions. ;-)
>
> In many (most?) environments the CMIS server is embedded into a DMS
system
> or an application server or a cloud infrastructure or something similar,
> which does the authentication check before the request actually reaches
the
> CMIS implementation. For a standalone CMIS server a Servlet filter is the
> preferred approach.
> There are many different authentication approaches; standard and
proprietary
> approaches. If you can do the authentication by looking the request HTTP
> headers or checking a SSL client certificate, you should do that before
the
> request hits OpenCMIS. That is, an unauthenticated request is rejected
early
> and the request body is not read. But there are a few authentication
methods
> and authentication rules that require reading the request body first,
> because the authentication information is in the body. For example, if
the
> UsernameToken authentication is used in the Web Service binding the user
> name and password are in the body. A proprietary authentication method
might
> check for a custom parameter that contains an additional secret or an
> application identifier or something similar.
> The body cannot be read twice. If you read the body in a filter, you
break
> at least all CMIS calls that accept content. OpenCMIS has to read the
body.
> To allow those authentication methods that require data from the body,
> OpenCMIS provides multiple places where those checks can be done with
full
> access to the body. In this case you are right. Reading and managing the
> body consumes resources, which will be lost if the authentication is
> rejected. OpenCMIS makes sure that a malicious client cannot send an
> infinite stream of data, but if your resources are smaller than the
built-in
> OpenCMIS limits you are in trouble. In the end it's up to the developers
and
> operators if that is acceptable or not. I wouldn't do it.
>
>
> - Florian
>
>
>
>> Whilst working on a CMIS server implementation I happened to be
>> examining the CmisBrowserBindingServlet class and noticed that for
>> HTTP POST requests POSTHttpServletRequestWrapper is instantiated
>> before any authentication checks are carried out (e.g. before
>> getCallContextHandler() is invoked where a TokenHandler can check the
>> request).
>>
>> POSTHttpServletRequestWrapper appears to process multi-part requests
>> as soon as it is created, getting an output stream to store data.
>>
>> Unless I am mistaken (and forgive me if I am), it is conceivable that
>> this approach is vulnerable to Denial of Service attacks: you can send
>> a bunch of POST requests with multi-part data to the server that will
>> cause it to allocate memory (if less than memory threshold) and or
>> temp file space (if greater than memory threshold) and exhaust system
>> resources.
>>
>> I would suggest that authentication should be checked before
>> processing multi-part requests in keeping with best practices (e.g.
>> rejecting unauthenticated requests as soon as possible).




Re: Security related question

Posted by Emrul Islam <em...@emrul.com>.
Hi Florian

I understand the considerations here and accept that most usages will
see a servlet filter to carry out authentication.  I still think a
documentation comment or similar would be really helpful because it is
an implementation detail that is not easily apparent - please consider
that as a suggestion.

For my use case its easy enough for me to patch my version of OpenCMIS
and move the token handling code earlier in the request processing
(which I can do because I don't need to read the body).  I also agree
that servlet filters are typically where this is done but it isn't an
option in my case since Servlet 3 Asynchronous processing doesn't play
well with servlet filters on all app servers - but that's unrelated to
the Chemistry project.

Thanks for your speedy reply!



On Wed, Aug 17, 2016 at 4:30 PM, Florian Müller <fm...@apache.org> wrote:
> Hi,
>
> You are right - with a few exceptions. ;-)
>
> In many (most?) environments the CMIS server is embedded into a DMS system
> or an application server or a cloud infrastructure or something similar,
> which does the authentication check before the request actually reaches the
> CMIS implementation. For a standalone CMIS server a Servlet filter is the
> preferred approach.
> There are many different authentication approaches; standard and proprietary
> approaches. If you can do the authentication by looking the request HTTP
> headers or checking a SSL client certificate, you should do that before the
> request hits OpenCMIS. That is, an unauthenticated request is rejected early
> and the request body is not read. But there are a few authentication methods
> and authentication rules that require reading the request body first,
> because the authentication information is in the body. For example, if the
> UsernameToken authentication is used in the Web Service binding the user
> name and password are in the body. A proprietary authentication method might
> check for a custom parameter that contains an additional secret or an
> application identifier or something similar.
> The body cannot be read twice. If you read the body in a filter, you break
> at least all CMIS calls that accept content. OpenCMIS has to read the body.
> To allow those authentication methods that require data from the body,
> OpenCMIS provides multiple places where those checks can be done with full
> access to the body. In this case you are right. Reading and managing the
> body consumes resources, which will be lost if the authentication is
> rejected. OpenCMIS makes sure that a malicious client cannot send an
> infinite stream of data, but if your resources are smaller than the built-in
> OpenCMIS limits you are in trouble. In the end it's up to the developers and
> operators if that is acceptable or not. I wouldn't do it.
>
>
> - Florian
>
>
>
>> Whilst working on a CMIS server implementation I happened to be
>> examining the CmisBrowserBindingServlet class and noticed that for
>> HTTP POST requests POSTHttpServletRequestWrapper is instantiated
>> before any authentication checks are carried out (e.g. before
>> getCallContextHandler() is invoked where a TokenHandler can check the
>> request).
>>
>> POSTHttpServletRequestWrapper appears to process multi-part requests
>> as soon as it is created, getting an output stream to store data.
>>
>> Unless I am mistaken (and forgive me if I am), it is conceivable that
>> this approach is vulnerable to Denial of Service attacks: you can send
>> a bunch of POST requests with multi-part data to the server that will
>> cause it to allocate memory (if less than memory threshold) and or
>> temp file space (if greater than memory threshold) and exhaust system
>> resources.
>>
>> I would suggest that authentication should be checked before
>> processing multi-part requests in keeping with best practices (e.g.
>> rejecting unauthenticated requests as soon as possible).

Re: Security related question

Posted by Florian Müller <fm...@apache.org>.
Hi,

You are right - with a few exceptions. ;-)

In many (most?) environments the CMIS server is embedded into a DMS 
system or an application server or a cloud infrastructure or something 
similar, which does the authentication check before the request actually 
reaches the CMIS implementation. For a standalone CMIS server a Servlet 
filter is the preferred approach.
There are many different authentication approaches; standard and 
proprietary approaches. If you can do the authentication by looking the 
request HTTP headers or checking a SSL client certificate, you should do 
that before the request hits OpenCMIS. That is, an unauthenticated 
request is rejected early and the request body is not read. But there 
are a few authentication methods and authentication rules that require 
reading the request body first, because the authentication information 
is in the body. For example, if the UsernameToken authentication is used 
in the Web Service binding the user name and password are in the body. A 
proprietary authentication method might check for a custom parameter 
that contains an additional secret or an application identifier or 
something similar.
The body cannot be read twice. If you read the body in a filter, you 
break at least all CMIS calls that accept content. OpenCMIS has to read 
the body. To allow those authentication methods that require data from 
the body, OpenCMIS provides multiple places where those checks can be 
done with full access to the body. In this case you are right. Reading 
and managing the body consumes resources, which will be lost if the 
authentication is rejected. OpenCMIS makes sure that a malicious client 
cannot send an infinite stream of data, but if your resources are 
smaller than the built-in OpenCMIS limits you are in trouble. In the end 
it's up to the developers and operators if that is acceptable or not. I 
wouldn't do it.


- Florian


> Whilst working on a CMIS server implementation I happened to be
> examining the CmisBrowserBindingServlet class and noticed that for
> HTTP POST requests POSTHttpServletRequestWrapper is instantiated
> before any authentication checks are carried out (e.g. before
> getCallContextHandler() is invoked where a TokenHandler can check the
> request).
> 
> POSTHttpServletRequestWrapper appears to process multi-part requests
> as soon as it is created, getting an output stream to store data.
> 
> Unless I am mistaken (and forgive me if I am), it is conceivable that
> this approach is vulnerable to Denial of Service attacks: you can send
> a bunch of POST requests with multi-part data to the server that will
> cause it to allocate memory (if less than memory threshold) and or
> temp file space (if greater than memory threshold) and exhaust system
> resources.
> 
> I would suggest that authentication should be checked before
> processing multi-part requests in keeping with best practices (e.g.
> rejecting unauthenticated requests as soon as possible).