== How to fix it in Flask === Code examples ==== Noncompliant code example [source,python,diff-id=204,diff-type=noncompliant] ---- from flask import Flask, request from flask_bcrypt import Bcrypt app = Flask(__name__) bcrypt = Bcrypt(app) @app.get("/") def hash(): password = request.args.get('password', '') hashed_password = bcrypt.generate_password_hash(password, rounds=2) # Noncompliant return f"
{hashed_password.decode('utf-8')}
" ---- ==== Compliant solution [source,python,diff-id=204,diff-type=compliant] ---- from flask import Flask, request from flask_bcrypt import Bcrypt app = Flask(__name__) bcrypt = Bcrypt(app) @app.get("/") def hash(): password = request.args.get('password', '') hashed_password = bcrypt.generate_password_hash(password) return f"{hashed_password.Decode('utf-8')}
" ---- === How does this work? include::../../common/fix/password-hashing.adoc[] include::../../common/fix/bcrypt-parameters.adoc[] include::../../common/fix/argon-parameters.adoc[] To use values recommended by the Argon2 authors, you can use the two following objects: * https://argon2-cffi.readthedocs.io/en/stable/api.html#argon2.profiles.RFC_9106_HIGH_MEMORY[argon2.profiles.RFC_9106_HIGH_MEMORY] * https://argon2-cffi.readthedocs.io/en/stable/api.html#argon2.profiles.RFC_9106_LOW_MEMORY[argon2.profiles.RFC_9106_LOW_MEMORY] To use values recommended by the OWASP, you can craft objects as follows: [source, python] ---- import argon2 from argon2.low_level import ARGON2_VERSION, Type OWASP_1 = argon2.Parameters( type=Type.ID, version=ARGON2_VERSION, salt_len=16, hash_len=32, time_cost=1, memory_cost=47104, # 46 MiB parallelism=1) # To apply the parameters to the Flask app: def set_flask_argon2_parameters(app, parameters: argon2.Parameters): app.config['ARGON2_SALT_LENGTH'] = parameters.salt_len app.config['ARGON2_HASH_LENGTH'] = parameters.hash_len app.config['ARGON2_TIME_COST'] = parameters.time_cost app.config['ARGON2_MEMORY_COST'] = parameters.memory_cost app.config['ARGON2_PARALLELISM'] = parameters.parallelism # ---- # Or the unofficial way: from flask import Flask from flask_argon2 import Argon2 app = Flask(__name__) argon2 = Argon2(app) argon2.ph = OWASP_1 set_flask_argon2_parameters(app, OWASP_1) ---- === Pitfalls include::../../common/pitfalls/pre-hashing.adoc[] === Going the extra mile include::../../common/extra-mile/argon-cli.adoc[] include::../../common/extra-mile/peppering.adoc[]