Avoiding PAM checks Bug 9892

Andreas Maier <[email protected]> Mon, 25 Aug 2014 15:13:35 +0200
Newsgroups gmane.network.open-pegasus.general
Message-ID <OFA335E7FB.25CE6D8A-ONC1257D3F.0043B4B8-C1257D3F.0048A7A7@de.ibm.com>
Kirk,
On your statement:
> If you use a cookie, then the server will have to request it each time
and cause excess wasted traffic.
I was not aware that in order to use cookies, the server has to turn around
and ask the client. The proposed approach would cause the server to include
the cookie in the response header of the response it sends anyway, and the
client would include the so received cookie in the request header of any
subsequent requests it sends anyway. That would not incur any additional
traffic.
Are you saying that the proposed approach cannot work that way?

On DMTF involvement:
DMTF would be involved to document the concept as an optional feature in
DSP0200, as it does already with a number of other HTTP headers (both
standard and extension). Reason being that DMTF wants to foster
interoperability across *multiple* implementations, instead of just
allowing a particular implementation between its client and server to do
something that is allowed as per the HTTP standard, but otherwise not known
outside of that particular implementation. Now that is Andy's view on how
DMTF operates, but it is with my DMTF hat (particularly the CIM-XML hat)
on.... Plus, IBM uses CIM clients and servers form multiple
implementations, so we have also a company interest for interoperability.

Andy

Andreas Maier
IBM Senior Technical Staff Member, Systems Management Architecture & Design
IBM Research & Development Laboratory Boeblingen, Germany
[email protected], +49-7031-16-3654
________________________________________________________________________
IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

----- Forwarded by Andreas Maier/Germany/IBM on 25.08.2014 14:19 -----

From:	Kirk Augustin <[email protected]>
To:	Karl Schopmeyer <[email protected]>, Jan Safranek
            <[email protected]>, Andreas Maier/Germany/IBM@IBMDE,
            OpenPegasus Developer mailing list <[email protected]>
Date:	31.07.2014 20:50
Subject:	Avoiding PAM checks Bug 9892



Seems overly complicated to me.
The sessionID should be sent by the client with every single packet
transmitted.
If you use a cookie, then the server will have to request it each time and
cause excess wasted traffic.
It does not matter what is in the sessionID, because the point is only for
the server to get back what it expects, regardless of what that is, so I
don't see how the DMTF is involved?
Cookies can return whatever you put into them, but is not really intended
for session integrity, but maintain continuity between sessions.
A lot of client systems do not allow cookies because they take up space and
are server intrusion on the client.
Sure cookies are small, but attacks planting billions of cookies have been
known to happen, once any cookies are allowed.

Kirk  Augustin
11821 NW McNamee Rd
Portland, OR 97231


HM: 503-289-4356

From: Karl Schopmeyer <[email protected]>
To: Jan Safranek <[email protected]>; Andreas Maier <[email protected]>;
OpenPegasus Developer mailing list <[email protected]>
Sent: Thursday, July 31, 2014 10:47 AM
Subject: Re: Avoiding PAM checks Bug 9892

My real concern was that the design depended on the cookie header which
without some extension to the DMTF protocol specs meant that OpenPegasus
had a "non-compliant" extension as part of its protocol for at least
cim/xml
and that should be considered for the other protocols also (wsman,
etc.). It is
HTTP compliant but not the DMTF specifications.

Given that Andy has agreed that we could propose some part of this to
the DMTF cim/xml
team as a proposed extension, and Jan's responses below which really
represent
a fairly simple solution that only passes the temporary ID back to the
client
in the cookie header (everything else is stored in the server including the
timeout information) which the client must return to ask the server to
bypass
PAM I think we are down to a couple of issues:

1. Exactly what should be in the sessionID.
2. Use of the cookie headers to pass this authentication state
information (sessionID) versus other
    means to pass the information.


SessionID

1. Andy notes that the the exact form of the SessionID is up for
discussion but that
was based on the SessionID carrying real information whereas Jan defined
it as
just a random number ID (all real information is only in the server).
It would
appear that the simple ID proposed is really adequate and that the
server may elect to
test other information received in WBEM requests containing a cookie (IP
address, etc.)
to what level of security it desires.

2.

Protocol Basis for passing session information between server and client

It is clear from the documentation that while there are many recognized
deficiencies throughout
the life of the cookie, it is the dominate mechanism for passing any
type of state information.

My only concern was that we do not want anything that cannot be met by a
conformant WBEM
client (i.e. Open Pegasus secret sauce).  Thus, if we accept that the
concept of the cookie is
the logical way to pass state information like this, then the
significant additional requirement on
the DMTF specifications is that a WBEM client may return a cookie if it
receives a Set-Cookie:
response from the WBEM server and that a WBEM server may include a
Set-Cookie header in
a WBEM response.

This is a specialized and specific use of the cookie header concept. As
such it would appear:

1. The cookie in the WBEM client has a life of a session where the
session is defined by the server and
    possibly limited by the WBEM client.
    If a Set-Cookie: header is received by the client it sends the
cookie back to that server with the subsequent
    operations for the same session and can then discard the cookie.
This is more specific than
    the general use of cookies in a browser/web server environment.
    As such, there is no need for the expiration date option (Expires=)
or the other optional components that
    are defined in RFC 6265 at least for the patches proposed as the
Pegasus implementation.

2. The concept of session is completely by the server. It creates a
session once it
    has validated the request, creates the sessionID, times out the
session, and has a way
    to tell the client when the session has timed out ( error 401,
Unauthorized)

If defined in an extension to the cim/xml specification, the requirement
would simply be that:

    a. The WBEM Server and WBEM client may use the HTTP cookie header
fields as defined in HTTP
        specifications. Note that the original specification was RFC
2109 which was superceeded by
        2965, which was, in turn, superceeded by 6265 so we should be
referenceing 6265 I think.
        This defines the Cookie: and Set-Cookie: header fields

b. A WBEM server may receive a WBEM request message that includes a
cookie header field
        as defined in the HTTP specifications that includes cookies
defined in a previous WBEM
        response message

    c. A Client that receives a WBEM response containing a set-cookie
header should
        return that cookie in the subsequent requests for the same session.

    d. A Server may include a cookie header in a cim/xml response
containing one or
        more cookies based on the HTTP specification.

In fact the only real changes to the DMTF specification are probably
that a WBEM server response
may include a cookie header (set_cookie:) and if it does, the WBEM
client may include that cookie
in subsequent requests.

Note that the current patch defines the cookie name as "PEGASUS_SID"
which is an OpenPegasus
defined name and pretty much ties this particular cookieto OpenPegasus.
Since the cookie name is
server generated and is only to be used to send the cookie back to the
server with the next request
for the same session, the actual name is effectively meaningless.






On 07/31/2014 02:40 AM, Jan Safranek wrote:
> On 07/30/2014 04:34 PM, Andreas Maier wrote:
>> Karl, Jan, I have discussed the issue with a number of folks, and
>> that helped me to better understand how Jan's proposal works.
>>
>> I'd like to make the following comments, before I leave for vacation
>> (back at home from 8/16 on, back in the office from 8/25 on):
>>
>> Just to recap the overall approach: Upon successful authentication of
>> a CIM request, if the server supports the new feature, it invents a
>> session ID and sends that back with the CIM response. If the client
>> supports the new feature, it uses that session ID on subsequent CIM
>> requests. Upon receipt of a CIM request with such a session ID, the
>> server can decide whether it trusts the session ID sufficiently at
>> that moment to bypass the authentication check.
>>
>> I'm fine with that overall approach, but I kept the description
>> deliberately high level, because there are some considerations and
>> requirements:
>>
>> - It depends very much on the data that makes up the session ID. A
>> suggestion from one of our security folks was that the session ID be
>> a hash of (userid, timestamp, randon number, underlying SSL session
>> ID). It is definitely a requirement that the session ID cannot be
>> calculated by an intruder. For example, just using timestamp and
>> userid would probably be not sufficient. Keep in mind that the code
>> is open source, so the algorithm how exactly the hash is calculated
>> will be known, and the secret must be in the data, not in the
>> algorithm. Using the underlying SSL session ID for example ensures
>> that the same SSL session is still in place. Maybe that is too much
>> of a requirement, but it is something that needs to be carefully
>> considered.
>>
> Currently, the session ID is just cryptographically strong* random
> number, nothing else. Timestamp, source IP address and client user name
> are stored (and checked) in Pegasus memory, but are *not* transmitted in
> the session id.
>
> *) 15 bytes (120 bits), generated by RAND_bytes() call from
> openssl/rand.h. I've chose 15 as 'long enough' and divisible by 3, so it
> can be base64-encoded without padding. It can be longer, it's just one
> #define.
>
> I think that adding anything else to the session ID won't improve
> security in any way, it will just make it more predictable. We may store
> (and check) something on server, if we want. I would explicitly avoid
> checking SSL session ID, as the client may use different TCP connection
> (and thus SSL session) for subsequent request - that's very common in
> HTTP world, clients (e.g. pywbem) don't use Keep-Alive that much.
>
>> - The server must be able to determine the lifetime of the session
>> ID. The proposed cookie based approach would probably use the cookie
>> lifetime for that, but that could also be done otherwise. Can cookie
>> lifetimes be modified by a client? That would be bad. I would have a
>> better feeling if the lifetime was encoded in the session ID instead
>> of being a separate piece of clear data. Even if the session ID is a
>> hash (which cannot be unpacked), the server could remember (in
>> memory) which session IDs it has handed out at any point in time, and
>> match the session ID with an internal record of it that shows the
>> lifetime.
> The cookie lifetime is stored on server, client cannot influence it in
> any way. As I wrote above, it's not part of session ID, as it would make
> the ID more predictable.
>
>> - The server must be allowed to decide at any point that a normally
>> valid session ID is nevertheless dismissed, and that a new session ID
>> is created. The server can make that determination based upon nearly
>> everything, including suspicuous client behavior with otherwise
>> valid requests. If the server dismisses an incoming session ID, it
>> performs the normal authentication as if no session ID had been
>> provided by the client, and returns a new session ID.
> Well, there is no code for that, but if someone implements such
> detection logic, it's just one HashTable.remove() call to forget a
> session. which implies that the next request will go through proper
> authentication.
>
>> - As a result, the client must always use the session ID returned by
>> the last response, because the server could have recalculated it.
> Sure, that's how HTTP and my client patches work.
>
>> - how the session ID is transported between client and server, has a
>> number of options. It would certainly be some HTTP header. I have
>> seen extension headers used for that purpose, it does not necessarily
>> have to be a cookie. I find cookies generally suspicious, and don't
>> fully understand to what extent HTTP infrastructure (e.g. proxies)
>> can have a policy to not allow them, in which case a cookie based
>> approach would be limiting in such environments.
> Cookie is described as HTTP 1.0 extension in RFC 2109: HTTP State
> Management Mechanism, released in 1997. It has been revised several
> times and it is part of any decent HTTP implementation for ages. To be
> honest, I haven't looked for any other RFC for session management over
> HTTP, the cookie is really used everywhere.
>
> RFC 2616 (HTTP 1.1) says: Unrecognized header fields SHOULD be ignored
> by the recipient and MUST be forwarded by transparent proxies.
>
> So, client who do not support cookies SHOULD survive just with Basic
> authentication in every request, just like now. And proxies MUST forward
> the cookie.
>
>> - Obviously, it must be optional to support for both client and
>> server. Just to have it mentioned.
> The server is configurable.
>
> What benefit it has to turn it off on _client_ side? If a client
> receives a cookie, it indicates that the server supports it. The client
> just sends it back in subsequent requests. If the server decides that
> the cookie is not enough, the client processed 401 Unauthorized response
> as usual.
>
>> - One important consideration is whether we want it to work with both
>> HTTP and HTTPS, and with all HTTP authentication mechanisms. Someone
>> needs to draw the matrix of HTTP/HTTPS with supported authentication
>> mechanisms, and state for which ones the session ID approach would be
>> supported. That may shape the design significantly. For example, if
>> we supported it only for HTTPS, the session ID would not need to be
>> encrypted. If we also wanted to support it for HTTP, we maybe want to
>> see it encrypted.
> As the session ID is just a random number, encrypting it on HTTP won't
> help much, especially without proper handshake protocol to exchange
> keys, which you don't have on HTTP.
>
> In addition, it looks quite funny that cookie should be encrypted, while
> Basic authentication (the only one that Pegasus supports now) sends user
> password unencrypted in a HTTP header.
>
>
>> - There are sufficient screws and decisions in that whole approach,
>> so that we cannot assume this is just an OpenPegasus addition.
>> DSP0200 documents all standard HTTP headers that play a role in
>> CIM-XML, and it would need to describe this new ability as well. Karl
>> and I are in the CIM-XML WG, and it should not take very long, once
>> we have agreed upon the details on how to do it.
>>
>> To me, the open points are: - how to calculate the session ID. This
>> could be a recommendation for servers to keep them secure, because it
>> is opaque for clients. - which mechanism to use to transport the
>> session ID between client and server.
> I hope I explained my design and implementation above, feel free to ask
> anything.
>
> Jan
>