Module 16 Exercises: Securing the Vault

Module 16 Exercises: Securing the Vault

Practical exercises to challenge your understanding of password security, resource ownership, and input sanitization.

Module 16 Exercises: Securing the Vault

Building an API is an act of trust. These exercises will help you ensure that trust is never broken.


Exercise 1: The Password Scrambler

You have a user signing up with the password "password123".

  1. Explain why you must use a Salt when hashing this password.
  2. Write the two-line passlib code needed to hash this password securely.

Exercise 2: Preventing the IDOR Attack

You have an endpoint @app.get("/invoices/{invoice_id}"). Write the logic inside this function that:

  1. Fetches the invoice from the database.
  2. Compares the invoice.owner_id with the current_user.id.
  3. Returns a 403 Forbidden if they don't match.

Exercise 3: The Update Shield

You are building a UserUpdate model.

  • Allowed fields to update: bio, profile_picture_url.
  • Secret fields that must NOT be updated: is_admin, balance.

Goal: Write the Pydantic model that ensures a user can't accidentally (or maliciously) update their admin status or balance via a standard PUT /profile request.


Self-Correction / Discussion

Exercise 1 Answer:

  1. Without a salt, two users with the same password ("password123") would have the exact same hash in your database. This allows an attacker to identify common passwords across your entire user base easily.
  2. from passlib.context import CryptContext
    pwd_context = CryptContext(schemes=["bcrypt"])
    hashed_password = pwd_context.hash("password123")
    

Exercise 2 Answer:

@app.get("/invoices/{id}")
async def get_invoice(id: int, user: User = Depends(get_current_user)):
    invoice = db.get_invoice(id)
    if invoice.owner_id != user.id:
        raise HTTPException(status_code=403, detail="Unauthorized")
    return invoice

Exercise 3 Answer:

Simply omit the sensitive fields from the model!

class UserUpdate(BaseModel):
    bio: str | None = None
    profile_picture_url: str | None = None
    # 'is_admin' and 'balance' are simply not here, so they can't be parsed from the JSON.

Summary of Module 16

You have built a "Bank-Grade" security layer for your app.

  • Hashing: You protect the keys to the kingdom.
  • Ownership: You ensure users stay in their own "Rooms."
  • Sanitization: You protect your logic from garbage data.

In Module 17: Deployment and Production, we will learn how to take your secure, high-performance API and launch it for the world to see.

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn