Hi Eoghan,
Great example. I hope I can clear up your confusion. In-line.
Glynn, Eoghan wrote:
-----Original Message-----
From: Polar Humenn [mailto:[EMAIL PROTECTED]
Sent: 12 February 2007 17:57
To: [email protected]
Subject: Re: HTTP Basic Authentication Is there hope?
Hi Eoghan,
I'm just going to clear up a few points below.
Thanks Polar for your patience in explaining this ...
However, I'm still a bit confused.
You correctly point out that the transitive nature of trust established
via signed certs is sometimes less than ideal, because some CAs are a
bit promiscuous.
So even if we're prepared to allow the TLS handshake to suceed and share
all sorts of other information with the endpoint, we draw the line at
exposing our Basic auth creds, unless some extra scrutiny is applied to
the TLS connection before reponding to the 401.
But the 401 may arrive for any request (not just the first one), so its
sortta orthogonal to the trust implicit in invoking individual
operations on the endpoint.
Say the client invokes on stock trading service that exposes two
operations:
placeOrder(String symbol, int volume, boolean sell, String account,
int PIN)
getQuote(String symbol)
Also the relevant port is HTTPS-based, and the client "trusts" the CA
signing the server's cert.
Now, consider the following sequence of events:
1. client establishes TLS connection, TLS handshake suceeds
Okay, so here we not only have a successful TLS handshake, which means
we have "trusted" the CA that signed the certificate. Before the
application should do step 2 below, it must be able to look up the
servers credentials (its Certificate) and decide whether to trust the
server with the "placeOrder" request. Trust in the authentication need
not be the same as trust in the server.
2. client needs to submit a sell trade, so it invokes placeOrder()
passing all sorts of sensitive information, i.e. its account number, PIN
etc.
Presumably, the client has done a trust evaluation and trusts the
authenticated server at this point.
3. later the client wants to check how the market reacted to its stock
sale, so it invokes getQuote() passing only innocuous info, i.e. the
ticker symbol its interested in.
Now, I'm not sure what you mean by "later". 2 Scenarios:
3a. Using HTTP/S connection has not dropped.
The application has decided to trust the server with placeOrder info,
so it assumes giving it a getQuote is okay.
Using HTTP/S connection has been reestablished
The application looks up the servers credentials, and makes
another trust
determination. If its the same server, sure. If not, it may or
may not
place the getQuote() depending on its trust evaluation for
getQuote information.
3b. Using HTTP
The application may assume since it's only innocuous information,
it will do the getQuote operation passing along innocuous
information.
4. the endpoint reacts to the getQuote with a 401, challenging the
client to provide its Basic auth creds
No problem here. If the server requires username/password, the client better
have one, or the service is denied, TLS or no TLS. Plain and simple.
What's the client going to do? Complain to the Queen? :)
5. now the client applies an extra level of scrutiny before providing
its creds
You are correct. I'm the client, and *me*, *myself*, and *I* happen
*value* that information because the handbook on security said not to
give my username and password combination to anybody, not to write it
down, etc except to that particular service. So, you bet your boots
cowboy, I'm going to check that server out before I give away the
jewels. :) just as I wouldn't have did a placeOrder() if the server
didn't pass my trust evaluation.
Obviously this is a pathological example, but you see where I'm going
with it. The server is free to challenge at any time, and the timing of
the challenge is not necessarily related to the true sensitivity of the
operations being invoked.
That's okay. Think of it as a kind of an access control scenario placed
in reverse.
What happens in access control?
A client makes a request on a server. That server checks out the
client's credentials before it will let the request succeed, allowing
access to certain resources, data, etc.
Okay, now turn the scenario around. The server is sort of a client in
this way. The server advertises a Service. That service in a sense is
"requesting" access to the client's resources, data, information. The
client makes an access control decision on that request.
The placeOrder operation requests sensitive information from the client.
The client makes an access control decision of whether to give that
information to the server.
The 401 response code requests sensitive information from the client.
The client makes an access control decision of whether to give that
information to the server.
It's the same thing. The server is "requesting" information, and the
client must make an access control decision on that request.
So it seems to me that if extra scrutiny is to be applied by the client,
it only makes sense not to wait for the 401 but instead to apply this
scrutiny from the get-go in the TLS handshake (e.g. via a programmatic
CertValidator, or even simpler by imposing constraints on the crypto via
the CipherSuiteFilters config item). That way the client can be sure
that *any* sensitive info to passes to the endpoint (whether in the form
of Basic auth creds or normal operation parameters) is protected by the
extra check.
I agree. It is best to only use TLS and make a trust decision based on
authentication. You run into some limitations:
1. The server does not use TLS.
You don't use its services.
2. The server issues a 401 over HTTP only.
You don't use its services.
Although, it can be said the above is "good" practice, it's not
realistic, and not practical. Furthermore, if CXF replaced remedies to 1
and 2 with "Not Supported", CXF users would probably go elsewhere
(instead of conform).
What would be preferable, is to provide the application developer with
hooks, interfaces, tools, to get at the authentication information (if
any), so that an application may make an informed decision about whether
to trust the target object, endpoint, port, whatever you call it.
In Adiron's ORBAsec SL3 (Secure CORBA) there is an operation on a
security manager interface:
TargetCredentials getTargetCredentials(CORBA::Object target);
The application uses the TargetCredentials interface to query
information about the channel (authenticated or not) set up to that
target object.
Did I help, or did I make it worse? :-[
Cheers,
-Polar
Does this make sense?
Cheers,
Eoghan
Glynn, Eoghan wrote:
Just configure a truststore (via the SSLClientPolicy TrustStore
element) that includes only the CAs that the client trusts.
Isn't that
the basis of all cert-based auth?
Cert-based Auth means that you merely trust the key-id
association provided by a trusted CA. It doesn't mean you
trust the id. George Bush may have a driver's license signed
from the State of Texas (CA), and I'll accept that that he is
George, his picture matches his face, and that Texas
certifies him to drive. However, I don't have trust him with
my car. The guy can't even navigate a coffee table. :)
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.
Now I'm confused. When would you accept a endpoint's "strong auth"
creds (i.e. the signed cert provided in the TLS handshake) and
possibly expose your own cert (if the endpoint requests it
during the
TLS handshake), but not be prepared to expose your own "weak auth"
creds (i.e. Basic auth username/passwd) to that endpoint?
With TLS you are "exposing" a piece of seemingly public
information, which is *not*, in the general case, sensitive
information. A certificate contains a name (DN) of the
Certificate Authority (CA), and the DN of the principal in
question, and the *public* key of that principal. Each end
can verify signatures, and authenticate each other without
exposing private keys, which is the sensitive information.
So, exposing your cert is merely like saying, "Hi, I'm Bob"
in a crowed room.
If the endpoint isn't worthy of
trust, why would it have a cert signed by a CA we trust.
We don't always have control over what CA's do with their signatures.
For example, a lot of bank server certificates are signed by
Verisign, but you don't have to trust them all. That is why
we have certificate cross-certification with certificate
constraints, but because of the complexity, nobody really
uses those. But, still, even so, that only gets you half-way there.
Or is it a question of degrees of trust? But if so, surely
accepting
the endpoint's cert is the bigger leap of faith than
handing out your
Basic auth username/passwd?
Before you hand out a sensitive username/password, you
authenticate the server through TLS with the analysis of the
certification chain, and also the quality of the "tunnel"
parameters: encryption algorithm, key length. Then separately
you evaluate the trust in the principal identified by the
certificate authentication. In this case you want to trust
the principal on the other end before you hand it sensitive
information.
Well the trust policy in effect is encoded in the
truststore, which is
in the client's domain and therefore under their control. So why
replicate this checking in the runtime?
The trust store only authenticates who is "speaking", so that
there is no (less probability of) impersonation. But then you
still must make a trust decision on whether to give that
principal what it asks for.
[snip]
That pretty much sums it up. And my (admittedly layperson's, and
perhaps
simplistic) notion was the following would give us all or
most of what
we need:
1. Extend AuthorizationPolicy to allow multiple per-realm/targetURI
username/password pairs to be configured.
This could be an acceptable approach, but shouldn't be the
only approach as you allude to in the following.
2. Allow (optional) programmatic retrieval of creds via
callback into
the app.
This is probably the most viable solution as it may allow for
prompting a user for authentication information, or going off
to some other trusted source for the information, a protected
file, trusted password service, etc, which is solely at the
discretion of the deployment.
3. Ensure the http client (either java.net.HttpUrlConnection or
commons
HTTPClient) can handle the 401 properly and associate it with the
appropriate creds.
This is a must for HTTP/S protocol, as this is the only way
to get the realm information. That part of the protocol is
required, so it must be supported when it comes about, i.e. 401.
4. Advise users that Basic auth should only be used over
HTTPS, unless
they don't care about creds being stolen or have reason to
trust HTTP
(e.g. the VPN case).
Agreed.
5. Require that users take responsibility for configuring
their trust
policies directly via their truststore.
This is always the case. I don't know how to *require* them
to do so, but we should not preclude them from doing the
thing that is right for them. The purpose is to give them to
tools to do a job that is suitable and is able to support the
security scrutiny, especially when it is mandated by certain
US laws, like HIPAA, FERPA, Sarbanes-Oxley and the privacy
laws of many European nations in the users' endeavors, and
maybe even write a value-added Common Criteria Protection
Profile, which may give their services some leverage in the
markets requiring security.
So, I believe this effort would take a number of tasks.
1. Building the callback mechanism.
2. Interface Framework to assign the call back mechanism
programatically.
3. Configuration to use a particular callback mechanism.
4. Configuration of realm/username/password combinations.
(My initial reaction is that #4 is configuration of
specialized default 3.)
Cheers,
-Polar
Cheers,
Eoghan