A RESTful authentication service for Flask applications
Project description
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.
Quickstart
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 myRealm 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('myRealm')
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.
Responses
- Unauthorized - 401
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 and return this.
- Challenge - 401
When the user does not provide an Authorization header or uses a stale nonce, the server will request authentication through an WWW-Authenticate header, which includes everything he needs to provide a valid response.
- BadRequest - 400
If the user’s Authorization header is missing a field, does not use the requested qop value or provides the wrong URI in the header, the server will deny access and return this.
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.
On top of that, it discards the nonce tokens after half an hour, automatically giving another one to the user, and it makes sure those tokens are only used from the IP for whom they were created.
Finally, it prevents you from storing the passwords in plaintext, offering instead an already hashed form of it when you call the method marked by the register decorator.
The result is that, using Flask Digest, you’ll be 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.
Criptoanalysis:
Chosen plaintext: malicious server chooses the nonce.
Precomputed dictionary: precomputed version of the above.
Batch brute force: chosen plaintext on multiple users at once.
Man-in-the-middle attacks, ie. 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 plaintext 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, ie. a brute force attack using a list of common passwords, do not permit your users to choose easy passwords. And to avoid spoofing tell them not to trust any server that doesn’t use Quality of Protection or whose qop value is not auth.
What the future holds
Logging of possible attacks
Implementation of auth-int
Adition of Authentication-Info header
Per user/resource authentication
Support Werkzeug’s views and blueprints
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Hashes for Flask_Digest-0.1.0-py2-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e7507a2ec2066ebd1cc44db3032c31e0a767f02c67f106359d7f4a21c31ef98b |
|
MD5 | 6638764d4dde1dde8cced4e474967958 |
|
BLAKE2b-256 | aa7bdd4cd039edc43b6b82c4dd45cc6032c331ec8a3400923d7fb763d0bdbebb |