Re: Avoiding PAM checks Bug 9892

Karl Schopmeyer <[email protected]> Thu, 31 Jul 2014 12:47:16 -0500
Newsgroups gmane.network.open-pegasus.general
Message-ID <[email protected]>
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
>