On Jan 11, 2009, at 10:07 AM, Emmanuel Dreyfus wrote:
Hello
I am not sure this is the right place for that question, but I cannot figure a better one. Please point me to the right place if there is a better one than here.
[[from openldap-software]]
I know how to use x509 certificate to authenticate a client against OpenLDAP. It works great with ldap{search|add|modify|delete| whatever}.`
Now I would like to do the same with the client being a web browser and with a web application between the browser and slapd:
browser (client cert) --> apache (PHP web application) --> slapd
Client certificate authentication from the browser to apache is strightforward.
Yes, so why complicate it?
Therefore I can easily have the client authenticating to the web application, and the web application operating on the directory on behalf on the client (the web app should bind to the directory as a privilegied user that would have authzTo: *)
The web application should just authenticate as itself and then use proxy authorization to act on behalf of the client. Of course, it has to be authorized to do so.
But it would be nicer to actually have the client authenticate to slapd using its own client certificate.
Why? Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
That is, having the web application behaving as a kind of proxy, without any special privilege on the directory. Is that possible? If it is, where should I start?
Would require cooperation between the web server and the directory server. So nothing gained, IMO, except complexity.
-- Emmanuel Dreyfus http://hcpnet.free.fr/pubz manu@netbsd.org
Kurt Zeilenga Kurt@OpenLDAP.org wrote:
Why? Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
When using plain password authentication, the web app can just hands the DN and password to slapd, it does not need any special privilege.
If the web app is entrusted with an authzTo: *, then a bug in it could be used to get full directory access.
That is, having the web application behaving as a kind of proxy, without any special privilege on the directory. Is that possible? If it is, where should I start?
Would require cooperation between the web server and the directory server. So nothing gained, IMO, except complexity.
This would be complexity in an unprivilegied piece of code, rather than giving trust to an application. Both approaches have merits. In order to really compare them, one need an idea of the complexity.
How would one implement that kind of "proxy certificate authentication"?
On Jan 11, 2009, at 11:22 AM, Emmanuel Dreyfus wrote:
Kurt Zeilenga Kurt@OpenLDAP.org wrote:
Why? Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
When using plain password authentication, the web app can just hands the DN and password to slapd, it does not need any special privilege.
But a bug in the web app could not only give access the directory for all subsequent users of the web app, but also to other information/ services protected by the user and password information available via that web application.
If the web app is entrusted with an authzTo: *, then a bug in it could be used to get full directory access.
That is, having the web application behaving as a kind of proxy, without any special privilege on the directory. Is that possible? If it is, where should I start?
Would require cooperation between the web server and the directory server. So nothing gained, IMO, except complexity.
This would be complexity in an unprivilegied piece of code, rather than giving trust to an application.
Not necessarily. The level of cooperation necessary, I believe, is so that the web app would have to be "trusted". And that's no better than the proxy authzid use case.
Both approaches have merits. In order to really compare them, one need an idea of the complexity.
How would one implement that kind of "proxy certificate authentication"?
I leave this as an exercise to someone who strong knowledge of TLS and its certificate-based authentication. I'm only saying it that it's likely possible, at least, in theory. I don't think it's practical.
-- Kurt
Kurt Zeilenga wrote:
On Jan 11, 2009, at 11:22 AM, Emmanuel Dreyfus wrote:
Kurt Zeilenga Kurt@OpenLDAP.org wrote:
Why? Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
When using plain password authentication, the web app can just hands the DN and password to slapd, it does not need any special privilege.
But a bug in the web app could not only give access the directory for all subsequent users of the web app, but also to other information/services protected by the user and password information available via that web application.
I thought a lot about the risks introduced by a web-based LDAP application. If a web application does not store user and password information because it keeps LDAP connections persistent in a web session then the risk is significantly lower than having a long-term service credential with a lot of power. (You might already have guessed web2ldap does it like this ;-)
That is, having the web application behaving as a kind of proxy, without any special privilege on the directory. Is that possible? If it is, where should I start?
Would require cooperation between the web server and the directory server. So nothing gained, IMO, except complexity.
This would be complexity in an unprivilegied piece of code, rather than giving trust to an application.
Not necessarily. The level of cooperation necessary, I believe, is so that the web app would have to be "trusted". And that's no better than the proxy authzid use case.
Kurt, one has to specify in detail "trusted for what". IMO proxy authorization is much more powerful than e.g. HTTP authentication with SPNEGO/Kerberos with the service being trusted to receive forwardable tickets (TGTs).
Both approaches have merits. In order to really compare them, one need an idea of the complexity.
How would one implement that kind of "proxy certificate authentication"?
I leave this as an exercise to someone who strong knowledge of TLS and its certificate-based authentication. I'm only saying it that it's likely possible, at least, in theory. I don't think it's practical.
I don't know of any existing mechanism one could use. Maybe a challenge-response SASL mech which uses Javascript signing at the client's side.
Ciao, Michael.
Kurt Zeilenga Kurt@OpenLDAP.org wrote:
I leave this as an exercise to someone who strong knowledge of TLS and its certificate-based authentication. I'm only saying it that it's likely possible, at least, in theory.
I thought a bit about it, here is my conclusions. Please tell me if I am wrong.
There is no way for a web app, (for instance written in PHP) to perform an SSL handshake with the browser. Apache does it, all it can do is to hand the client credentials to the web app, which executes after the SSL handshake took place.
I see a solution, though. When doing HTTP authentication using LDAP, Apache performs a ldap_bind using credentials given by the client. For now the LDAP handle obtained from ldap_bind is just forgotten. Apache could keep it and make it available to other modules (like mod_php) for them to perform LDAP operations on behalf of the client.
That would require 3 modifications 1) implement x509 certificate authentication in Apache runtime library (it only does ldap_bind_s using login/password for now) 2) save the LDAP handle somewhere 3) add a ldap_bind_preauth() function in mod_php so that PHP code can get the LDAP handle
There is something not very clear in my mind about how the LDAP handle can be sent from Apache to mod_php. Everything happens in the same process, so I guess an environement variable containing the address of the LDAP handle would do the trick, but is that reasonable?
Opinions? Is that plan pure science fiction, or is there something to experiment here?
Emmanuel Dreyfus wrote:
There is no way for a web app, (for instance written in PHP) to perform an SSL handshake with the browser. Apache does it, all it can do is to hand the client credentials to the web app, which executes after the SSL handshake took place.
Yes. However in theory the web app could run within a custom HTTP server and intercept the SSL/TLS handshake.
I see a solution, though. When doing HTTP authentication using LDAP, Apache performs a ldap_bind using credentials given by the client.
Are you talking about HTTP basic authentication. Yes, then the web server gets the clear-text password and the web app can access it too.
For now the LDAP handle obtained from ldap_bind is just forgotten. Apache could keep it and make it available to other modules (like mod_php) for them to perform LDAP operations on behalf of the client.
With HTTP basic authc you can get the clear-text password from env var REMOTE_PASSWORD. But you will not gain anything and it's better to implement form based password input since the browser caches the HTTP basic authc credentials.
That would require 3 modifications
- implement x509 certificate authentication in Apache runtime library
(it only does ldap_bind_s using login/password for now) 2) save the LDAP handle somewhere 3) add a ldap_bind_preauth() function in mod_php so that PHP code can get the LDAP handle
I don't fully understand your approach. How is the LDAP bind supposed to work end-to-end with your approach?
Ciao, Michael.
Michael Ströder michael@stroeder.com wrote:
Yes. However in theory the web app could run within a custom HTTP server and intercept the SSL/TLS handshake.
In fact I thought a bit more about it and I do not think it can work: if the HTTP server intercepts the SSL handshake and proxy it to slapd, then the SSL connexion will be between the web browser and slapd. The HTTP server will not be able to handle the request.
In fact we would need a double SSL handshake: one with the HTTP server and another one with slapd, proxyied by the HTTP server. I am not even sure it is possible.
Emmanuel Dreyfus wrote:
Michael Strödermichael@stroeder.com wrote:
Yes. However in theory the web app could run within a custom HTTP server and intercept the SSL/TLS handshake.
In fact I thought a bit more about it and I do not think it can work: if the HTTP server intercepts the SSL handshake and proxy it to slapd, then the SSL connexion will be between the web browser and slapd. The HTTP server will not be able to handle the request.
In fact we would need a double SSL handshake: one with the HTTP server and another one with slapd, proxyied by the HTTP server. I am not even sure it is possible.
Yes, now you see why the steps here
http://www.openldap.org/lists/openldap-technical/200901/msg00037.html
are necessary. You need secure handshakes between all three parties, and secure credentials that all three parties can trust.
Kurt Zeilenga wrote:
The web application should just authenticate as itself and then use proxy authorization to act on behalf of the client. Of course, it has to be authorized to do so.
But it would be nicer to actually have the client authenticate to slapd using its own client certificate.
Why?
I also concur that it would be nice to have a end-to-end authentication between web client and LDAP server without giving the web application special rights.
Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
BTW: This is a very broad assumption not valid in all deployments. Nevertheless it's always good practice to avoid overly powerful system components since in this case the web application could have security problems.
Kerberos with forwardable tickets could be a solution. One could argue that as a forwardable ticket is a full TGT you also have to trust the web application a little bit more. But given the limited lifetime of TGTs the risk is significantly lower than long-time service credentials for the web application together with the right for doing proxy authorization.
Ciao, Michael.
Michael Ströder wrote:
Kurt Zeilenga wrote:
The web application should just authenticate as itself and then use proxy authorization to act on behalf of the client. Of course, it has to be authorized to do so.
But it would be nicer to actually have the client authenticate to slapd using its own client certificate.
Why?
I also concur that it would be nice to have a end-to-end authentication between web client and LDAP server without giving the web application special rights.
But obviously the web application is a man-in-the-middle and current authentication mechanisms are designed to prevent MITM operation.
Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
BTW: This is a very broad assumption not valid in all deployments. Nevertheless it's always good practice to avoid overly powerful system components since in this case the web application could have security problems.
Kerberos with forwardable tickets could be a solution. One could argue that as a forwardable ticket is a full TGT you also have to trust the web application a little bit more. But given the limited lifetime of TGTs the risk is significantly lower than long-time service credentials for the web application together with the right for doing proxy authorization.
Still, that is your problem - you have to trust the web app to act appropriately on your behalf. If the web app has security problems, then sending any form of reusable credentials to it is a mistake.
As a hypothetical solution, one could use a combination of tickets and proxy authorization. I.e., the web app receives a client credential that contains both authentication to the web app and to the LDAP server. The web app then attaches (the relevant portion of) this credential to its proxyAuth'd requests to the LDAP server. The LDAP server then doesn't have to give blanket proxy privileges to the app; instead it allows the proxyAuth by virtue of the actual client credentials also being present.
In an X.509 framework, you might accomplish this by having clients generate their own sub-certificates (signed by their own client cert) with specific privilege attributes attached, and very short cert lifetimes (thus being analogous to Kerberos tickets in usage), and using these sub-certs to authenticate. Of course, nobody has developed a spec for any of this yet...
Howard Chu wrote:
Michael Ströder wrote:
Kurt Zeilenga wrote:
Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
BTW: This is a very broad assumption not valid in all deployments. Nevertheless it's always good practice to avoid overly powerful system components since in this case the web application could have security problems.
Kerberos with forwardable tickets could be a solution. One could argue that as a forwardable ticket is a full TGT you also have to trust the web application a little bit more. But given the limited lifetime of TGTs the risk is significantly lower than long-time service credentials for the web application together with the right for doing proxy authorization.
Still, that is your problem
Howard, that's not a matter of "your" or "my" problem. In fact I don't understand that sentence.
- you have to trust the web app to act
appropriately on your behalf. If the web app has security problems, then sending any form of reusable credentials to it is a mistake.
In an ideal world there are no security problems at all. The 2nd best situation is that you know for sure in advance whether a component has security problems or not. If it has it is a mistake to use it. Period.
But as we all know we're not living in an ideal world. So risk management generally deals with the probability and the impact of (most times unknown) risks. You can influence the probability by good software design, code reviews and such. But that's most times outside the scope of an administrator setting up a deployment. So the administrator can only think about mitigating the impact of possible risks. This is not a black-or-white situation.
And one could argue that the possible impact of security problems in combination with proxy authz is higher than with a user impersonating himself on the LDAP connection.
As a hypothetical solution, one could use a combination of tickets and proxy authorization. I.e., the web app receives a client credential that contains both authentication to the web app and to the LDAP server. The web app then attaches (the relevant portion of) this credential to its proxyAuth'd requests to the LDAP server. The LDAP server then doesn't have to give blanket proxy privileges to the app; instead it allows the proxyAuth by virtue of the actual client credentials also being present.
Well, that's IMHO how forwardable tickets in Kerberos works except that you don't need proxy authz in that game. (It's on my roadmap to play with it.)
In an X.509 framework, you might accomplish this by having clients generate their own sub-certificates (signed by their own client cert) with specific privilege attributes attached, and very short cert lifetimes (thus being analogous to Kerberos tickets in usage), and using these sub-certs to authenticate. Of course, nobody has developed a spec for any of this yet...
Why so complicated? A challenge-response SASL mech could send the challenge from the LDAP server to the web app which relays it to the web browser where the user signs it with his/her private key.
A similar password-based approach would be to map HTTP-DIGEST authc to SASL DIGEST-MD5. AFAIK that's not possible.
There are some SSO solutions for web apps. E.g. CAS issues a one-time service ticket (CAS-ST) which is checked by the service against the central CAS service. This could be sent along in a SASL bind request with a custom SASL mech and then checked by the LDAP server (see http://www.ja-sig.org/products/cas/overview/cas2_architecture/index.html). Or the app could send the CAS-ST in a simple bind request and an overlay would intercept this and check with the CAS server.
Ciao, Michael.
Michael Ströder wrote:
Howard Chu wrote:
Michael Ströder wrote:
Kurt Zeilenga wrote:
Generally, the web application is part of the service which encompasses the web server and directory service. They should already have an appropriate trust relationship.
BTW: This is a very broad assumption not valid in all deployments. Nevertheless it's always good practice to avoid overly powerful system components since in this case the web application could have security problems.
Kerberos with forwardable tickets could be a solution. One could argue that as a forwardable ticket is a full TGT you also have to trust the web application a little bit more. But given the limited lifetime of TGTs the risk is significantly lower than long-time service credentials for the web application together with the right for doing proxy authorization.
Still, that is your problem
Howard, that's not a matter of "your" or "my" problem. In fact I don't understand that sentence.
Generic "your" - probably should have said "the" instead.
- you have to trust the web app to act
appropriately on your behalf. If the web app has security problems, then sending any form of reusable credentials to it is a mistake.
And one could argue that the possible impact of security problems in combination with proxy authz is higher than with a user impersonating himself on the LDAP connection.
Yes, depending on how much freedom the proxying identity has. I should point out that OpenLDAP's ACLs allow you to define separate privileges for a user being proxied, vs a user that is authenticated directly. As such, you can easily limit the damage that an untrusted proxy can inflict on a system...
As a hypothetical solution, one could use a combination of tickets and proxy authorization. I.e., the web app receives a client credential that contains both authentication to the web app and to the LDAP server. The web app then attaches (the relevant portion of) this credential to its proxyAuth'd requests to the LDAP server. The LDAP server then doesn't have to give blanket proxy privileges to the app; instead it allows the proxyAuth by virtue of the actual client credentials also being present.
Well, that's IMHO how forwardable tickets in Kerberos works except that you don't need proxy authz in that game. (It's on my roadmap to play with it.)
But a forwardable TGT is like a blank check - it can be used to acquire any other service tickets. Again, if you don't trust the app in the middle, this is not a good solution.
In an X.509 framework, you might accomplish this by having clients generate their own sub-certificates (signed by their own client cert) with specific privilege attributes attached, and very short cert lifetimes (thus being analogous to Kerberos tickets in usage), and using these sub-certs to authenticate. Of course, nobody has developed a spec for any of this yet...
Why so complicated? A challenge-response SASL mech could send the challenge from the LDAP server to the web app which relays it to the web browser where the user signs it with his/her private key.
Because a scheme like what you describe is inadequate. One of the factors in strong authentication is *mutual* authentication of all parties - proving that the client is who he claims to be and the server is who it claims to be. A pass-thru scheme like you describe will prove the client and LDAP server's identity, but will not establish anything about the web app's authenticity. When you have multiple parties in a conversation, all of them must be authenticated to the same level of trust, otherwise the whole exercise is futile.
Howard Chu wrote:
Michael Ströder wrote:
Howard Chu wrote:
As a hypothetical solution, one could use a combination of tickets and proxy authorization. I.e., the web app receives a client credential that contains both authentication to the web app and to the LDAP server. The web app then attaches (the relevant portion of) this credential to its proxyAuth'd requests to the LDAP server. The LDAP server then doesn't have to give blanket proxy privileges to the app; instead it allows the proxyAuth by virtue of the actual client credentials also being present.
Well, that's IMHO how forwardable tickets in Kerberos works except that you don't need proxy authz in that game. (It's on my roadmap to play with it.)
But a forwardable TGT is like a blank check - it can be used to acquire any other service tickets.
Yes. But in opposite to a clear-text password typed in a web form the TGT has a limited lifetime like the short-time cert you proposed.
Again, if you don't trust the app in the middle, this is not a good solution.
Yes, but the trust is not a black-or-white decision. If I surely know that the web app is flawed it's a big mistake to use it anyway.
In an X.509 framework, you might accomplish this by having clients generate their own sub-certificates (signed by their own client cert) with specific privilege attributes attached, and very short cert lifetimes (thus being analogous to Kerberos tickets in usage), and using these sub-certs to authenticate. Of course, nobody has developed a spec for any of this yet...
Why so complicated? A challenge-response SASL mech could send the challenge from the LDAP server to the web app which relays it to the web browser where the user signs it with his/her private key.
Because a scheme like what you describe is inadequate. One of the factors in strong authentication is *mutual* authentication of all parties - proving that the client is who he claims to be and the server is who it claims to be. A pass-thru scheme like you describe will prove the client and LDAP server's identity, but will not establish anything about the web app's authenticity. When you have multiple parties in a conversation, all of them must be authenticated to the same level of trust, otherwise the whole exercise is futile.
"Web app's authenticity" is a very broad term. Even when authenticating the web server where the app is running by validating the SSL server cert you cannot verify the "web app's authenticity". So to some degree you have to trust the web app itself (like Kurt already mentioned). But again: Trust is not a black-or-white decision.
I see no reason why I shouldn't connect via HTTPS to the web app and then have a pass-through authentication mechanism between the web browser and the LDAP server to impersonate the user himself on the LDAP connection. This is pretty similar to the user typing in his password into a login form of the web app except that no clear-text longtime credential has to be passed to the web app. (With assuming the web app does not enforce any authorization at all and therefore does not have to authenticate the user.)
Ciao, Michael.
openldap-technical@openldap.org