I tend to [snip] quoted text a lot, so please pardon me if any of the responses appear out of context.

On Feb 12, 2007, at 9:27 AM, Glynn, Eoghan wrote:

Aside from the *bad practice* of keeping user name/password
combinations in unencrypted files,

I don't agree with you here that this is necessarily bad practice. In
fact some form of it seems unavoidable to me in the general case.

I think we could go on and on arguing the relative merits or demerits of storing passwords on the file system. I agree that there are cases in which it's needed -- as you've identified, unattended startup/clients. Some vendors attempt some sort of obfuscation in these cases, but this is pretty much pointless, as a secret just gets embedded in the code somewhere. (Google Steve Job's recent tirade on DRM, for why this is basically pointless) So yes, I agree, you're leaning on OS security in this case, and that's okay, in a limited set of cases.

In any event, I think the whole discussion of persistent stowage of passwords is a bit of a tangent, in the discussion at hand, so I propose we drop this particular issue, or at least move it off to the side, as long as there is a programmatic way to configure this information. (I'm still trying to understand the model enough to see if such programmatic config is possible)

In particular, since the creds are effectively sent in the clear (modulo base-64 encoding), surely if we want to keep these creds secret, then it
makes absolutely no sense to use basic auth over plain ol' HTTP?

Rather, auth based on this scheme should *only* be used over HTTPS.

Exactly. The question is, how do we enforce this condition? Seems to me the runtime needs to know somehow that the target has been authenticated in some manner, and in the case of HTTP, SSL is pretty much the only game in town. (Other transports may have other authentication mechanisms).

We could enforce this by ensuring that the AuthPolicy is accompanied by an appropriate setting of the SSLClientPolicy. But forcing the issue has the downside of excluding a valid "weak auth" use-case ... e.g. where we
don't care if the creds are stolen because they're not protecting
anything sensitive, but instead just drive some insecure personalization logic in the endpoint. Or say the VPN use-case, where HTTP is OK as its
tunneled securely.

I'm not sure how enforcing this would exclude the admittedly weak use case -- certainly any behaviors here could default to the recommended best practice ("Never, under any circumstances, reveal a password to an unauthenticated peer"). Any desired knobs could then be used to tweak this behavior, e.g., to turn off the requirement.

An aside: I agree that there are cases where HTTP/BA over an unprotected channel are potentially useful, but I'd like to think these are fairly degenerate cases. The VPN case is dangerous, because VPN traffic protects networks, not endpoints. So if you really do care about passwords, you kind of have to bend over backwards with your routers to ensure no one isn't listening in promiscuous mode somewhere on your network. It's doable, but it's relying on a lost of costly infrastructure. If we can agree that this case is degenerate, then I propose we move on.


We would like to examine certain aspects of the endpoint
before we start *exposing usernames and passwords to
everybody* with a pretty flower.
There is no apparent way to do this in CXF's use of HTTP.

Well to an extent there is some control here - we can configure the
SSLClientPolicy to require that the endpoint has a trusted cert.

Okay, now that's interesting.  What would we need to do to do this?

(I snipped the whole discussion of server interceptors and 401 -- sounds like an implementation detail I'm unfortunately not prepared to comment on, and I'm not sure how relevant it is to this discussion.)

Ok what we do now is what you might call preemptive auth, in the sense
that we send the Authorization header up-front without waiting to be
asked for it via a 401 challenge. Yes we could wait for the 401, but in
either case, trust establishment cannot be done via Basic auth alone.
IMO at least in order to mean anything, its got to be coupled with
HTTPS.

I think that's just the point Polar made -- sounds like everyone's in agreement on this.


Even this java.net.Authenticator is woefully inadequate as
there is now way too look up an SSL authentication on the
HttpURLConnection.

Do we really need to access the full details of the SSL authentication
at this point? Would a check via Authenticator.getProtocol() that HTTPS was indeed used, coupled with the client's knowledge of and control over
its own local truststore, not be sufficient?

I think we might. For example, it may not be enough that the endpoint uses SSL. What if, for example, you're using DH anonymous cipher suites? All you get there is data protection, which if you think about it, is vulnerable to man-in-the-middle attacks (in which case you don't really get data protection at all).

There may also be cases in which, say, for some authenticated endpoints, you are willing to disclose a password (it has a key signed by Zeus), whereas others you don't. So yeah, some details into the security features of the target could definitely be of use.

I'm also not sure if the coupling with control over the local trustdb is enough. How does the runtime know what the trust policies are in effect? If it's something that is outside of the control of the runtime, but rather at the discretion of the administrator ("Configure your endpoints thusly"), I suppose that's an approach one could take, but there's very little you could say in terms of assurance, at that point, and I think what we are after is wiring some sort of hooks into the runtime in order to be able to make assurance arguments about its behavior.

Here's the crux of the issue, what's a "good security solution", and
what sort of underlying mechanism is required to supply this goodness?
Is it reasonable to expect to able to build "hardened" security on a
foundation as shaky as Basic auth? There are other, less weak, HTTP
authorization mechanisms (Digest, NTLM etc.) that we could consider
instead.

Well, as Dan suggested, the same issue comes up with the WS-Security username-password profile. If you're going to send a username and password, you are going to need to ensure that the endpoint you're sending to is trustworthy. You may want the same assurance with other profiles. (Won't go into the details, but SAML through SOAP comes to mind).

Getting on to what I interpret the main point of the post, the question seems to apply to the granularity of the effective policies used at a client endpoint (or server, but I won't go there):

1. When endpoint policies are specified via config (leaving aside the question of programmatic configuration), the policies are identified in a bean, and are based on a QName. 2. In the case of HTTP/BA, the effective policy may be to send a username and password. 3. It seems possible for more than one client endpoint (potentially referencing 2 different endpoints) to be associated with, or identified by, the same QName. 4. Therefore, it's possible for a client application to inadvertently send its username and password to these 2 services, irrespective of any authentication that has or has not occurred of said targets.

I propose we stick to this issue (if I've characterized it correctly), and come to agreement about whether it is or is not a problem, and if it is, how we rectify it.

Thanks,
Fred

Reply via email to