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