Start learning free

LESSON 99 OF 188 · BACKEND: USERS AND SECURITY

Don't Let Clients Set Everything in Python

Practice

A sign-up sends a JSON body, and a client can put any keys in it, not only the ones your form asks for. If your code saves every key as a column, the client chooses what gets stored: "role": "admin" makes an admin, and "id": 1 tries to take the admin's id. This hole is called mass assignment.

The fix is an allowlist: a list of the keys a client may set. You build the new row yourself and copy only the keys on your list. Everything else in the body is ignored. Here is the idea for a review form:

REVIEW_FIELDS = ["stars", "text"]

review = {}
for field in REVIEW_FIELDS:
    if field in data:
        review[field] = data[field]

Then answer with what the database stored, not with what the client sent. Ana asks to be an admin and becomes a customer. Ben asks for id 50 and gets the next free id:

POST /register  {"email": "ana@example.com", "password": "secret123", "name": "Ana Pop", "city": "Cluj", "role": "admin", "id": 1}
  →  201  {"city": "Cluj", "email": "ana@example.com", "id": 2, "name": "Ana Pop", "role": "customer"}
POST /register  {"email": "ben@example.com", "password": "tea4two!", "id": 50, "role": "admin"}
  →  201  {"city": null, "email": "ben@example.com", "id": 3, "name": null, "role": "customer"}
POST /login  {"email": "ana@example.com", "password": "secret123"}
  →  200  {"token": "<token>"}
GET /me  (Authorization: Bearer <token>)
  →  200  {"email": "ana@example.com", "id": 2, "role": "customer"}
POST /products  {"name": "Desk", "price": 120}  (Ana's token)
  →  403  {"error": "Admins only"}

Your task: add the columns name and city to the users table and write the allowlist SIGNUP_FIELDS. In register, build new_user from that list, add the password's hash, save it with insert_row, and answer the stored row with 201.


Assignment
Follow the Coding Tutorial to close the mass assignment hole in POST /register with an allowlist.


Hint
Loop over SIGNUP_FIELDS, not over data: then the loop never even meets "role" or "id". Copy a field only if field in data, so a missing name simply stays empty.


STEP 1 OF 10
    Ctrl + Enter to check

    Sec Mass Assignment in Python

    Keep going with Python1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free