Logging out with AuthTktAuthenticationPolicy

72 views
Skip to first unread message

Mike Orr

unread,
Jun 20, 2017, 1:01:05 PM6/20/17
to pylons-...@googlegroups.com
Originally I used SessionAuthenticationPolicy because the code was
straightforward and what I was doing before. I mentioned the
seemingly-duplicate code between '*CookieSessionFactory' and
AuthTktAuthenticationPolicy and whether it could be merged, because it
was long and complicated (and hard for me to understand, all that
cookie signing and setting stuf). Somebody recommended
AuthTktSessionFactory anyway saying it's not necessarily a great idea
to put your authentication in your session. I'm not sure I fully agree
with that, but I switched to AuthTktSessionFactory anyway.

Now I'm wondering, how does AuthTktAuthenticationPolicy enforce
logouts? With SessionAuthenticationPolicy it deletes the userid in the
server-side session, and if the server wants to reject somebody with
prejudice or clear all sessions it can delete the session backend
object. But with AuthTktSessionFactory as I understand it, it merely
sends a header to the client expiring the cookie. What if the client
ignores that directive? Would the person still have authenticated
status? Does the server keep a record somewhere of which tokens are
still valid? (Akin to storing the ID in the session.) If not, how does
it know whether to reject the cookie because it previously invalidated
the token? Does this mean SessionAuthenticationFactory is actually
more secure than AuthTktAuthenticationFactory?

--
Mike Orr <slugg...@gmail.com>

Bert JW Regeer

unread,
Jun 20, 2017, 2:35:09 PM6/20/17
to pylons-...@googlegroups.com
AuthTkt relies on the browsers goodwill, what you are looking for is a way for you to expire an authentication session server side:

https://usingnamespace.gitlab.io/pyramid_authsanity/faq.html#why-tickets

Explains why you want to have the ability to expire sessions ahead of time.

I don’t agree with storing authentication session information in the session because they have two very different concerns/lifetimes. Sessions should store temporary data that may be useful across a user switching from one page to another, but should not store long-term information. Whereas authentication is usually longer lived, and has different concerns regarding the ability to expire/verify it is still valid.

Storing the authentication in the session can be handy, and if you are already storing that somewhere server side and you can attribute a session not just to a session id but also to a user to force a logout, then it would work just fine.

AuthTkt can’t be merged with the CookieSessionFactory stuff because AuthTkt as a policy is meant to work together with Apache’s AuthTkt module or any other code using AuthTkt. It is a lot like using JWT. It allows a single server (the authentication server) to sign and provide the user with a “token” they can use to authenticate against a different server/endpoint with that “token” and that other server doesn’t have to do any checking other than verifying the signature that yes the user is authenticated.

However this has the flaw, as you saw that you can’t expire the authentication server side, you have to trust that the client listened when you asked them to remove the “token” and no longer use it to connect to a server.

Besides JWT being an incredibly complex standard that every so often you read about yet another library that implemented it poorly (and thus leading to security issues) it has the same flaws as AuthTkt.

pyramid_authsanity is my auth policy that tries to fix some of these issues. It can use the existing session, or another cookie, or even authorization header, and does server side checking that the ticket in the token has not expired or been removed. This allows for example a single user logged in from 3 different locations to easily de-authenticate the two other locations by clicking a button to remove some entries from the database.

Using SessionAuthenticationFactory with a server side session implementation is slightly more secure, however the default session implementation which stores sessions in cookies (and thus has no server side state at all) has the same issues as AuthTkt in that expiration of the cookie is something the client has to abide by.

Bert
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To post to this group, send email to pylons-...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/CAH9f%3Duqt%3D_i-eus-VHWeSEO%3DNasWkfTiSr0YgvnjWQZv6_quDA%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

Mike Orr

unread,
Jun 20, 2017, 11:59:05 PM6/20/17
to pylons-...@googlegroups.com
On Tue, Jun 20, 2017 at 11:34 AM, Bert JW Regeer <xist...@0x58.com> wrote:
> I don’t agree with storing authentication session information in the session because they have two very different concerns/lifetimes. Sessions should store temporary data that may be useful across a user switching from one page to another, but should not store long-term information. Whereas authentication is usually longer lived, and has different concerns regarding the ability to expire/verify it is still valid.

I guess my use cases are different. My organization wants idle logins
to time out in a shortish period of time so people don't leave the
site logged in and then somebody else comes to the computer and starts
using their privileges. So the time limit for an idle login and an
idle session is about the same (e.g., 15 minutes, 1 hour, 4 hours, 8
hours depending on how strict and inconveniencing we want to be.) and
I don't see why they can't be the same. And if the session gets lost
for some other reason along the way, well, that's one of the basic
weaknesses of the web.

> AuthTkt can’t be merged with the CookieSessionFactory stuff because AuthTkt as a policy is meant to work together with Apache’s AuthTkt module or any other code using AuthTkt. It is a lot like using JWT. It allows a single server (the authentication server) to sign and provide the user with a “token” they can use to authenticate against a different server/endpoint with that “token” and that other server doesn’t have to do any checking other than verifying the signature that yes the user is authenticated.

I don't know how to set up multi-platform auth tokens, if ti goes
beyond just sharing the cookie. Athough our organization wants to move
to an OAuth server (which they don't have yet although they have a
limited one) so that will be kind of like a ticket. Another group has
a Django app that has OAuth, so I figure when they get it set up with
the central server they can show me how.

How do you tell AuthTktAuthenticationFactory which foreign tokens to
honor, if Apache or a central server sets one?

> However this has the flaw, as you saw that you can’t expire the authentication server side, you have to trust that the client listened when you asked them to remove the “token” and no longer use it to connect to a server.
>
> Besides JWT being an incredibly complex standard that every so often you read about yet another library that implemented it poorly (and thus leading to security issues) it has the same flaws as AuthTkt.
>
> pyramid_authsanity is my auth policy that tries to fix some of these issues. It can use the existing session, or another cookie, or even authorization header, and does server side checking that the ticket in the token has not expired or been removed. This allows for example a single user logged in from 3 different locations to easily de-authenticate the two other locations by clicking a button to remove some entries from the database.
>
> Using SessionAuthenticationFactory with a server side session implementation is slightly more secure, however the default session implementation which stores sessions in cookies (and thus has no server side state at all) has the same issues as AuthTkt in that expiration of the cookie is something the client has to abide by.

I'm using 'pyramid_redis_sessions'. I can't guarantee that session
values will fit within cookie limits, because one application stores
all the search result IDs to page through them and there could be five
thousand. Although that application is still in Pylons. Still, I think
the cookie-value limit is too low for many session use cases. I think
I'll go back to SessionAuthenticationFactory.

Mike Orr

unread,
Jun 21, 2017, 12:05:22 AM6/21/17
to pylons-...@googlegroups.com
On Tue, Jun 20, 2017 at 11:34 AM, Bert JW Regeer <xist...@0x58.com> wrote:
> AuthTkt relies on the browsers goodwill, what you are looking for is a way for you to expire an authentication session server side:
>
> https://usingnamespace.gitlab.io/pyramid_authsanity/faq.html#why-tickets

That says that storing the user ID in a cookie is a bad idea, but
isn't that what AuthTktAuthenticationFactory does? It says that it's
better to have a server-side list of valid tokens, but does
AuthTktAuthenticationFactory have that and if so where? If it doesn't,
why is it called a ticket, because it seems to be the non-ticket the
article is disrecommending. Whereas if the server did have a list of
valid tickets, then it could just delete the ticket, and then if the
client comes back with a ticket-cookie that should have expired, the
application can tell the browser where to go.

Bert JW Regeer

unread,
Jun 21, 2017, 12:46:33 PM6/21/17
to pylons-...@googlegroups.com

> On Jun 20, 2017, at 21:58, Mike Orr <slugg...@gmail.com> wrote:
>
> On Tue, Jun 20, 2017 at 11:34 AM, Bert JW Regeer <xist...@0x58.com> wrote:
>> I don’t agree with storing authentication session information in the session because they have two very different concerns/lifetimes. Sessions should store temporary data that may be useful across a user switching from one page to another, but should not store long-term information. Whereas authentication is usually longer lived, and has different concerns regarding the ability to expire/verify it is still valid.
>
> I guess my use cases are different. My organization wants idle logins
> to time out in a shortish period of time so people don't leave the
> site logged in and then somebody else comes to the computer and starts
> using their privileges. So the time limit for an idle login and an
> idle session is about the same (e.g., 15 minutes, 1 hour, 4 hours, 8
> hours depending on how strict and inconveniencing we want to be.) and
> I don't see why they can't be the same. And if the session gets lost
> for some other reason along the way, well, that's one of the basic
> weaknesses of the web.
>
>> AuthTkt can’t be merged with the CookieSessionFactory stuff because AuthTkt as a policy is meant to work together with Apache’s AuthTkt module or any other code using AuthTkt. It is a lot like using JWT. It allows a single server (the authentication server) to sign and provide the user with a “token” they can use to authenticate against a different server/endpoint with that “token” and that other server doesn’t have to do any checking other than verifying the signature that yes the user is authenticated.
>
> I don't know how to set up multi-platform auth tokens, if ti goes
> beyond just sharing the cookie. Athough our organization wants to move
> to an OAuth server (which they don't have yet although they have a
> limited one) so that will be kind of like a ticket. Another group has
> a Django app that has OAuth, so I figure when they get it set up with
> the central server they can show me how.
>
> How do you tell AuthTktAuthenticationFactory which foreign tokens to
> honor, if Apache or a central server sets one?

It’s based upon the secret (i.e. the signing key)

>
>> However this has the flaw, as you saw that you can’t expire the authentication server side, you have to trust that the client listened when you asked them to remove the “token” and no longer use it to connect to a server.
>>
>> Besides JWT being an incredibly complex standard that every so often you read about yet another library that implemented it poorly (and thus leading to security issues) it has the same flaws as AuthTkt.
>>
>> pyramid_authsanity is my auth policy that tries to fix some of these issues. It can use the existing session, or another cookie, or even authorization header, and does server side checking that the ticket in the token has not expired or been removed. This allows for example a single user logged in from 3 different locations to easily de-authenticate the two other locations by clicking a button to remove some entries from the database.
>>
>> Using SessionAuthenticationFactory with a server side session implementation is slightly more secure, however the default session implementation which stores sessions in cookies (and thus has no server side state at all) has the same issues as AuthTkt in that expiration of the cookie is something the client has to abide by.
>
> I'm using 'pyramid_redis_sessions'. I can't guarantee that session
> values will fit within cookie limits, because one application stores
> all the search result IDs to page through them and there could be five
> thousand. Although that application is still in Pylons. Still, I think
> the cookie-value limit is too low for many session use cases. I think
> I'll go back to SessionAuthenticationFactory.
>
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To post to this group, send email to pylons-...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/CAH9f%3DuodeBZ9X%2BqMCcS%3DcxRKNmfgJpUD5tXYbuEJ4qb%2BOBufiw%40mail.gmail.com.

Bert JW Regeer

unread,
Jun 21, 2017, 2:42:59 PM6/21/17
to pylons-...@googlegroups.com

> On Jun 20, 2017, at 22:05, Mike Orr <slugg...@gmail.com> wrote:
>
> On Tue, Jun 20, 2017 at 11:34 AM, Bert JW Regeer <xist...@0x58.com> wrote:
>> AuthTkt relies on the browsers goodwill, what you are looking for is a way for you to expire an authentication session server side:
>>
>> https://usingnamespace.gitlab.io/pyramid_authsanity/faq.html#why-tickets
>
> That says that storing the user ID in a cookie is a bad idea, but
> isn't that what AuthTktAuthenticationFactory does?

Yes, and my implementation does too. However what is referred to there is when people do:

authentication=yourusername

or

authentication=userid

And just add that to a cookie. That is what allows trivial “attacks” whereby an attacker just changes the cookie to say “authentication=adminaccount” and now they have an admin account.

AuthTkt goes a step further in that it stores the userid/username and signs it, so it can’t be spoofed, but there is no expiration server side, that is where having a ticket server side comes in.

> It says that it's
> better to have a server-side list of valid tokens, but does
> AuthTktAuthenticationFactory have that and if so where?

It does not have this.

> If it doesn't,
> why is it called a ticket, because it seems to be the non-ticket the
> article is disrecommending.

Yup.

> Whereas if the server did have a list of
> valid tickets, then it could just delete the ticket, and then if the
> client comes back with a ticket-cookie that should have expired, the
> application can tell the browser where to go.

Exactly what you want

--

It’s overloading the language of what a ticket is. In AuthTkt the “ticket” is the cookie. In my case the tickets are per authentication “tickets” that are compared on the backend to the front-end. I guess I could clear up the language or change it or use something like “token” but that also has a very specific connotation for people.

The important thing is that you can invalidate an existing authentication without a client being involved.

Bert

Michael Merickel

unread,
Jun 21, 2017, 2:51:12 PM6/21/17
to Pylons
On Wed, Jun 21, 2017 at 1:42 PM, Bert JW Regeer <xist...@0x58.com> wrote:
AuthTkt goes a step further in that it stores the userid/username and signs it, so it can’t be spoofed, but there is no expiration server side, that is where having a ticket server side comes in.

In an attempt to clarify one point - an auth_tkt ticket can also contain and sign the timestamp when the ticket was created such that you / the policy can prevent someone replaying a cookie long after it was created. However if you want any sort of assurance that the user still exists inside that valid range of time you *will* need to verify that ticket server-side (backend query to see if the userid is still valid). This is an issue with any client-side scheme including auth_tkt or jwt. This is what the callback/groupfinder is for in the pyramid policy and obviously pyramid_authsanity supports a way to verify the ticket with your backend as well.

Jonathan Vanasco

unread,
Jun 21, 2017, 4:11:12 PM6/21/17
to pylons-discuss

On Tuesday, June 20, 2017 at 1:01:05 PM UTC-4, Mike Orr wrote:
That says that storing the user ID in a cookie is a bad idea, but 
isn't that what AuthTktAuthenticationFactory does?


Storing a user_id AS the cookie payload for auth is a bad idea.  Storing a user_id IN a signed (or encrypted) payload however is usually fine.

A common TERRIBLE authentication policy is to have plaintext username/userid data as a cookie.  That can easily be spoofed, stolen, etc.


I'll try to explain what many others have already said slightly differently...


One common improvement to insecure session concept is to use a signed cookie payload.  The cookie may have the user_id in it, but the payload would be in a structure like this:

    payload['timestamp'] = time.time()
    serialized_payload = serialize(payload)
    signature = sign_payload(serialized_payload, site_secret))
    cookie_value = ':'.join([serialized_payload, signature])

A timestamp is added to the payload to limit how long it is effective for, it's then serialized and signed.
The server can reject any cookies for being before a certain timestamp, or signed with the wrong secret.
An attacker knowing the user_id is irrelevant, because they can't craft a payload signature.  
The weakness is that the cookie itself could be intercepted and stolen.
 
AuthTkt is another common improvement to Sessions and can either work alongside an encrypted/signed session OR in place of it.

In the original Apache mod_perl implementation (which became mod_auth_tkt in c, IIRC), an authtkt was basically a signed cookie that simply authenticated a username+ip combo as "valid" for a fixed time.  It was pretty lightweight and done (in part) to offload database session checking -- which was heavy then.  It had routines to be tracked/checked server-side though, so a developer could revoke a specific ticket (instead of cycling out a shared secret - which would revoke them all).

Modern AuthTkt implementations -- like Bert's -- have a lot of hooks for more granular permissions and server-side checking, as this stuff is all incredibly simple and rather lightweight now.

One of the neater things with AuthTkts is that it becomes a bit easier to have "global" server side sessions for a user.  i.e. you can have a single user with multiple devices/auth-tkts, and each ticket authorizes to a shared session on the server (e.g via the user id).  


Reply all
Reply to author
Forward
0 new messages