New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authorizing only some users #4

Open
chmduquesne opened this Issue Jul 6, 2013 · 5 comments

Comments

Projects
None yet
2 participants
@chmduquesne

chmduquesne commented Jul 6, 2013

Hi,

With apache mod-auth-openid, you can filter users:

require user http://myopenid.com/myusername/

If I am not mistaken, there is no way to do that with mod-auth-ticket. Is there a plan to implement that?

It would be useful in situations where you are hosting static content that you want to limit to a specific set of authenticated users.

@tai

This comment has been minimized.

Owner

tai commented Jul 11, 2013

Hi chmduquesne,

It is possible, or at least, it should (= if not, that is a bug) be possible.
It can be done by using mod_auth_ticket (MAT) along with standard mod_auth module (or any other module, as long as its hook is called after MAT's hook).

I think I tested this long long time ago, but I'll check again.

Internally, MAT converts incoming "signed cookie" into HTTP "Authorization:" header.
So as long as username:password pair embedded in "signed cookie" matches with a entry in htpasswd file, you should be able to add additional protection using mod_auth's syntax.

Note there is no way for you or MAT to know user's real password - because that part is offloaded to external authentication service (IdP, in OpenID/etc speak). You can just come up with any random text for password field and emded that when generating a cookie - just make sure both MAT and mod_auth use same "randomly-generated" password. I think HASH(username + mod_auth_ticket_secret) would do.

Just FYI, my plan is to make MAT embed other information embedded in "signed cookie" into HTTP header (or environment var), so it'll be extremely flexible when used in conjunction with mod_magnet (lua script).

I was recently hit by mod_auth limitation that it still does not handle group authentication, so I decided to embed group information into "signed cookie", let MAT convert it to HTTP header, and use mod_magnet to check (and filter) that incoming request.

@chmduquesne

This comment has been minimized.

chmduquesne commented Jul 12, 2013

On Fri, Jul 12, 2013 at 1:33 AM, Taisuke Yamada notifications@github.comwrote:

Internally, MAT converts incoming "signed cookie" into HTTP
"Authorization:" header.
So as long as username:password pair embedded in "signed cookie" matches
with a entry in htpasswd file, you should be able to add additional
protection using mod_auth's syntax.

Ok, that is what I thought: the password does not really matter, and you
can use whichever you want as long as it is in the passwd file.

Note there is no way for you or MAT to know user's real password - because

that part is offloaded to external authentication service (IdP, in
OpenID/etc speak). You can just come up with any random text for password
field and emded that when generating a cookie - just make sure both MAT and
mod_auth use same "randomly-generated" password. I think MD5(username +
mod_auth_ticket_secret) would do.

Looks good to me.

Another question: from what I understand, in the php form, the (username +
password) string will be used to build a cookie that is then passed to MAT.
More precisely if I get this right, the cookie key is "crypt", and the
value is the xor of text=b64(username + password) and
key=mod_auth_ticket_secret.

This cookie is stored into the user's computer for a few seconds (and then
goes back to MAT). Does not this risk to expose the mod_auth_ticket_secret?
One of the things with xor encryption is that xor(text, cyphertext)=key.
The user knows about the beginning of the text (the username is his openid
username, the password is unknown) and he sees the cyphered text. If the
key is shorter than the username (which can be pretty long, or at least
chosen long on purpose), I believe that you can find the key easily.

If I still get this right, with this key, one could forge identities, using
it to build a cookie and directly log into lighttpd as a different user.

What do you think? Am I not getting something right?

@tai

This comment has been minimized.

Owner

tai commented Jul 12, 2013

Yes, you're correct. And that is why MAT uses time-salted, hashed temporary key for actual encryption. Even if attack-able, that window of opportunity will be limited to 5-10 seconds. My assumption was that it should do to protect from replay attack based on leaked cookie.

However, as you pointed out, current encryption method is not strong enough if a user who wants to attack another user can control one's username length. Stronger scheme was planned with "srp:" scheme, but that is still not implemented.

I think I can come up with "crypt2:" scheme, which adds username as a salt for temporal key generation. That way, each temporary key is now "per-user", so there's no way one user can attack another user. I'll try that this weekend.

Just as a record, primary reason why MAT uses simple XOR-based scheme is that I wasn't able to find "common encryption" that works across various programming languages. Obviously there's AES/etc in OpenSSL, but each openssl wrapper (in each programming language) seems not to agree on actual encryption parameter, and was not interoperable. So when I made MAT to work with PHP+openssl generated cookie, that implementation had a issue with another. Thus I ended up with current scheme.

@chmduquesne

This comment has been minimized.

chmduquesne commented Jul 12, 2013

Why do you even want to encrypt username:password?

From what I understand, it does not really matter if this information goes
public, because it is only used to filter users after they have been
externally verified by their openid provider, and only if we want to filter
some of them. Anyone who knows about this username:password combination
cannot do much with it, because they first need the openid mechanism to
authentify them.

I have the impression that you could put this username:password combination
in clear in the cookie, and just have the php page sign the cookie
(Preferably using a time-based hmac mechanism:
https://en.wikipedia.org/wiki/Hash-based_message_authentication_code,
because it was specifically designed for signing messages without
compromising the key and without being vulnerable to length-extension
attacks). Then you would verify that the cookie is correctly signed server
side, which guarantees you that it was signed by someone who had the key:
your php page. You can then switch to whatever mechanism after that.

Again, I just have superficial understanding of your code, that I read
quickly, so I may have gotten something wrong...

@chmduquesne

This comment has been minimized.

chmduquesne commented Jul 15, 2013

So, what do you think? If you are interested in my proposal, I can try
to implement it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment