pyramid_authsanity

pyramid_authsanity is an authentication policy for the Pyramid Web Framework that strives to make it easier to write a secure authentication policy that follows web best practices.

  • Uses tickets to allow sessions to be prematurely ended. Don’t depend on the expiration of a cookie for example, instead have the ability to terminate sessions server side.

  • Stops session fixation by automatically clearing the session upon login/logout. Sessions are also cleared if the new session is for a different userid than before.

  • Automatically adds the Vary HTTP header if the authentication policy is used.

pyramid_authsanity uses Michael Merickel’s absolutely fantastic pyramid_services to allow an application developer to easily plug in their own sources, and interact with their user database.

API Documentation

Reference material for every public API exposed by pyramid_authsanity:

pyramid_authsanity

Authentication Service Policy

class pyramid_authsanity.AuthServicePolicy(debug=False)[source]
authenticated_userid(request)[source]

Returns the authenticated userid for this request.

effective_principals(request)[source]

A list of effective principals derived from request.

forget(request)[source]

A list of headers which will delete appropriate cookies.

remember(request, principal, **kw)[source]

Returns a list of headers that are to be set from the source service.

unauthenticated_userid(request)[source]

We do not allow the unauthenticated userid to be used.

pyramid_authsanity.interfaces

SourceService

interface pyramid_authsanity.interfaces.IAuthSourceService[source]

Represents an authentication source.

get_value()

Returns the opaque value that was stored.

headers_forget()

Returns any and all headers for forgetting the current requests value.

headers_remember(value)

Returns any and all headers for remembering the value, as a list. Value is a standard Python type that shall be serializable using JSON.

vary

List of HTTP headers to Vary the response by.

AuthService

interface pyramid_authsanity.interfaces.IAuthService[source]

Represents an authentication service. This service verifies that the users authentication ticket is valid and returns groups the user is a member of.

add_ticket(principal, ticket)

Add a new ticket for the principal. If there is a failure, due to a missing/non-existent principal, or failure to add ticket for principal, should raise an error

groups()

Returns the groups for the current user, as a list. Including the current userid in this list is not required, as it will be implicitly added by the authentication policy.

remove_ticket(ticket)

Remove a ticket for the current user. Upon success return True

userid()

Return the current user id, None, or raise an error. Raising an error is used when no attempt to verify a ticket has been made yet and signifies that the authentication policy should attempt to call verify_ticket

verify_ticket(principal, ticket)

Verify that the principal matches the ticket given.

pyramid_authsanity.sources

Session Authentication Source

pyramid_authsanity.sources.SessionAuthSourceInitializer(value_key='sanity.')[source]

An authentication source that uses the current session

Authorization Header Authentication Source

pyramid_authsanity.sources.HeaderAuthSourceInitializer(secret, salt='sanity.header.')[source]

An authentication source that uses the Authorization header.

Narrative Documentation

Narrative documentation that describes how to use this library, with some examples.

The authentication policy

This authentication policy has two moving pieces, they work together to provide an easy to use authentication policy that provides more security by allowing the server to terminate an active authentication session.

Source Service

The first piece is called the authentication source service, this stores the principal and a ticket. There are two provided source services:

session

This source stores the information required for the authentication in the Pyramid session, this requires that a session is available in the application as request.session. Since there is no requirement for a Pyramid application to have a registered session, pyramid_authsanity decided to not make this the default.

Authentication Service

The authentication service is defined by the user, the primary goal is to verify that the principal and ticket are both still valid.

Other Matters

Frequently Asked Questions

Why tickets?

If you have a web application that uses a simple signed cookie that contains information about the signed in user, the login will not expire until the cookie’s expiration. This can leave gaps in security.

Take the scenario of an employee that uses their own device for business, they log in in the morning before heading into the office and the cookie is set to authenticate them for 12 hours. They go buy some coffee and put their phone down. Walking out they leave the phone on a table. Once they find out they notify the company about the lost phone, however since the authentication cookie is their username, there is no way to terminate the existing session, and were an attacker able to use their phone they would be able to continue using the web application for the next 12 hours.

Tickets are stored server side, and for each device/login there will be a unique ticket. These can be individually removed, and as soon as it is removed the authentication is no longer valid.

Facebook/Google for example also allow the user to view their sessions, and terminate one, or all of them. This ticket based system allows for the same user interaction, thereby allowing more control over who is logged in or why.

If a user changes their password, tickets give the ability to log out all pre-existing sessions so that the user is required to login again on any and all devices.

What is session fixation?

Session fixation is an attack that permits an attacker to hijack a valid session. Generally this is done by going to the website and retrieving an session, that session is then given to the victim. As soon as the victim logs in, the attacker who still has the same session token is able to see what is being stored in the session which may potentially leak data. For authentication policies that store the authentication in the session this would give the attacker full control over the victim’s account.

You stop session fixation by dropping the session when going across an authentication boundary (login/logout). This will recreate the session from scratch, which leaves the attacker with a session that is worthless.

Vary headers

When an HTTP request is made, the content is usually cached for as long as possible to avoid having to do more trips to the backend server (for reverse proxies) and more requests to the server for browsers. However proxies and browsers can’t know that the page for example contains information that is dependent on a particular HTTP header, that is where the vary HTTP header comes in.

Using vary you can tell the proxies or web browser that this page is to be cached, but it is dependent on a particular header. For example vary: cookie means the cache is allowed to return the page without requesting information from the backend server so long the cookie the client sends is the exact same as at the time of the previous response generated.

For more take a look at RFC7231 section 7.1.4 which explains what this header does and means.

License

Copyright (c) 2015-2017 Bert JW Regeer;

Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.