Link Search Menu Expand Document

Mass Assignment in Python

Using Flask

Vulnerable Example

In the below example of a vulnerability, the parameters coming from an HTTP request are deserialized to a Python dictionary to then be used in a downstream context, for example a SQL query. The logic below allows a malicious user to override a sensible field in a SQL insert query:

@object.route("/insert", methods=['POST'])
def object_insert():
    # initialise the dictionary with a predefined value
    values = {'isAdmin': get_admin_status()}

    # update the values (sensitive_field may be overridden)
    values.update(request.form.to_dict(flat=True))

    # pass the dictionary to the SQL query
    sql_statement = 'INSERT INTO messages VALUES (:isAdmin, :values_from_user)'
    conn = sqlite3.connect('db.sqlite')
    conn.cursor().execute(sql_statement, values)
    conn.commit()
    return redirect("/", code=201)

The following POST request causes the insertion of true instead of get_admin_status() in isAdmin:

isAdmin=true&values_from_user=yyy

Prevention

Flask does not provide any specific control to prevent Mass Assignment; it is up to the developer to restrict the fields that are safe to be retrieved from an HTTP request:

values = {
    'isAdmin': get_admin_status(),
    'values_from_user': request.form.get('values_from_user')
}