Skip to main content

Flask Digest provides a RESTful way of authenticating users using a Flask application. To achieve that, it uses the Digest Access Authentication protocol and most optional features described in RFC 2617.

In a simplified manner, Flask Digest allows you to make your resources available only to those registered in your system, while taking care of security issues by following well known protocols.

Quick start

First of all, installation is as simple as:

$ pip install flask-digest

After doing that, it’s important to note this module is implementation-independent of how the user database is handled and accessed. So the first thing you need to do is set that up, including methods for registering users and accessing their passwords.

Then, you need to create a Stomach object and inform it of how to use the database you created. The only thing left now is to decide which resources should be protected and mark them accordingly.

All the steps regarding the Stomach object are done with the use of three decorator methods, similar to the ones used by Flask. Those are exemplified bellow, where realm is a string of your choosing, used to describe and identify your server in a unique fashion:

from flask import Flask
from flask_digest import Stomach

app = Flask(__name__)
stomach = Stomach('realm')

db = dict()

@stomach.register
def add_user(username, password):
    db[username] = password

@stomach.access
def get_user(username):
    return db.get(username, None)

@app.route('/')
@stomach.protect
def main():
    return '<h1> resource <h1>'

add_user('admin', '12345')
app.run()

Keep in mind that the protect decorator MUST be located between the chosen method and Flask’s route decorator.

Also, the method for registering new users is expected to receive a username as first parameter and a password as second. If you need to, other parameters are allowed as well.

As for the database access method, it should only have the username as required parameter, while returning the stored password or None if the username was not registered. For more advanced uses, notice that the request object is visible from this method, when called internally.

Accessing

Okay, now you know how to protect your resources. But how do you access them, with all this security casing? Depending on the context of your application, it can be quite simple. For example, most browsers already support this kind of authentication protocol out of the box!

If you’re thinking of accessing your stuff through another python script, you’re also in luck! There’s a module called Requests, which seamlessly supports Digest and will do all the work for you. I strongly recommend checking it out.

On the other hand, if it’s written in another language there’s no easy solution I can offer. Either you look for another module with that functionality or create one yourself. In any case, make sure to tell me how it went, so I can share your experience here.

Bellow, there’s a small list of possible response codes you can get when making a request to a protected resource and their causes. If the code you got is not in this list, it probably wasn’t generated by Flask Digest.

Responses

401 Unauthorized

When the user provides an invalid combination of username/password, uses a nonce created for another IP or provides a wrong nc, the server will deny access to the resource.

However, if the user does not provide an Authorization header or uses a stale nonce, the server will include a WWW-Authenticate header, with everything he needs to provide his credentials.

400 BadRequest

If the user’s Authorization header is missing a field, does not use the requested qop value or provides the wrong uri, the server will deny access to the resource.

Features

This implementation of the Digest Authentication scheme uses the Quality of Protection (qop) optional feature. More specifically, it forces you to use the auth variation of it, since it makes the protocol much more secure. Also, it discards the nonce tokens after half an hour and makes sure they are only used from the IP for whom they were created.

Besides authenticating users, Flask Digest also makes it possible for the client to authenticate the server. This is done by using the Authentication-Info header, as it contains a hash that could only be produced if one knew the client’s credentials. This header is included on every successful response.

Regarding user database security, the register decorator does not allow you to store passwords in plain text, offering instead a digest of the user’s credentials to the underlying method when it is called.

All of this together results in your application being protected against the following attacks:

  • Replay: the request is intercepted and reproduced in the future

  • Reflection: attacker repasses the server’s challenge to the user

  • Cryptanalysis

    • Chosen plaintext: malicious server chooses the nonce

    • Precomputed dictionary: precomputed version of the above

    • Batch brute force: chosen plain text on multiple users at once

Man-in-the-middle attacks, i.e. intercept and modify requests, are also prevented regarding the request URIs, but until auth-int is implemented entity bodies CAN be modified. So POST and PUT methods are still vulnerable.

Recommendations

Even thought Flask Digest doesn’t allow you to store plain text passwords, it’s still a good idea to encrypt the file in some way. Also, if maintaining multiple realms, make sure their names differ, so that a security breach in one doesn’t affect the other.

To avoid online dictionary attacks, i.e. a brute force attack using a list of common passwords, do not permit your users to choose easy passwords. And to avoid spoofing do not trust any server that doesn’t use Quality of Protection and have the clients also authenticates the server.

Changelog

To check out the complete changelog, click here.

What the future holds

  • Logging of possible attacks

  • Implementation of auth-int

  • Per user/resource authentication

  • Support Werkzeug’s views and blueprints

Release files for Flask-Digest 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for Flask-Digest 0.3.0
File Size Uploaded
Flask-Digest-0.3.0.tar.gz 7.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for Flask-Digest 0.3.0
File Interpreter ABI Platform
Flask_Digest-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.9 kB

Release files / Flask-Digest-0.3.0.tar.gz

Download URL Flask-Digest-0.3.0.tar.gz
Size 7.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1758e3fc2abf2d2214fc59b00fd4e7e2a7c2efe530e1386a92e55dfb52b16b7d
BLAKE2b-256 checksum
How to use checksums
89614160f37399bc49299ab2727ba373826b442626096bc377460f0e27a3b294
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.7

Release files / Flask_Digest-0.3.0-py3-none-any.whl

Download URL Flask_Digest-0.3.0-py3-none-any.whl
Size 7.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e13183f7ea3ffaa87217b4d5275ac5f1bd7d1d85550df6ee5def25e5668b6e1
BLAKE2b-256 checksum
How to use checksums
67a2dca0aecd7ebbc1954798812be5812b7445300924ebdb6e7186be4f6f765e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.7

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.1

1 release file

0.2.0

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page