Start learning free

LESSON 1 OF 20 · SECURITY: COMMON ATTACKS

Security Headers

Practice

Every answer your Flask app sends starts with headers: short lines like Content-Type: text/html that the browser reads before the page. Some headers are instructions that close holes in the browser itself.

The attack: another site, say prize.example, loads the shop's /account page inside an invisible frame and lays it exactly over its own "Win a prize!" button. The visitor aims at the prize, but the click lands on Delete my account. This is called clickjacking. What the attacker gets: a click on the shop's button that the visitor never meant to make.

Three headers close three holes. X-Frame-Options: DENY tells the browser never to show the page inside a frame. X-Content-Type-Options: nosniff tells it to trust the Content-Type and never guess, so a file sent as plain text is never run as a script. Referrer-Policy: no-referrer tells it not to send the shop page's address to the next site when the visitor follows a link.

One function for every answer: a function marked with @app.after_request gets each response just before Flask sends it, even Flask's own error pages. It can change the response, and it must return it. This one, for example, asks browsers not to keep a copy of any page:

@app.after_request
def no_cache(response):
    response.headers["Cache-Control"] = "no-store"
    return response

With your function in place, all four answers the check asks for carry X-Content-Type-Options: nosniff, X-Frame-Options: DENY and Referrer-Policy: no-referrer, whatever the route and the status:

GET /account      →  200  <h1>Your account</h1><form …><button>Delete my account</button></form>
GET /products/1   →  200  {"category": "kitchen", "id": 1, "name": "Mug", "price": 12, "stock": 10}
GET /products/99  →  404  {"error": "Product not found"}
GET /admin        →  404  (Flask's HTML error page)

Your task: add a function add_security_headers(response) with the decorator @app.after_request. It sets X-Content-Type-Options to "nosniff", X-Frame-Options to "DENY" and Referrer-Policy to "no-referrer", then returns the response.


Assignment
Follow the Coding Tutorial to add the three security headers to every answer the shop sends.


Hint
Headers work like a dictionary: response.headers["Name"] = "value". Don't forget return response: Flask sends what the function returns.


STEP 1 OF 6
    Ctrl + Enter to check