Re: Avoiding PAM checks - Whoops
Karl Schopmeyer <[email protected]> Fri, 01 Aug 2014 10:04:26 -0500
| Newsgroups | gmane.network.open-pegasus.general |
|---|---|
| Message-ID | <[email protected]> |
Whoops, I sent out a reply to this yesterday that was really still an early draft and was both incomplete and incorrect. Will complete and resend today. Karl 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 >