Content security policy explained using Flask
If you want to improve the security of your website, you can use a content security policy to help detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. Basically, a content security policy tells the browser which origins it is allowed to load data from. CSP can be enabled by setting the Content-Security-Policy
HTTP response header.
Let's look into this further using a simple Flask app.
Simple Flask app
We will use a Flask extension called Talisman. Here is our main code file:
app.py
from flask import Flask, redirect, render_template, request, url_for
from flask_talisman import Talisman
app = Flask(__name__)
csp = {
'default-src': '\'self\''
}
talisman = Talisman(app, content_security_policy=csp)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
@app.route("/youtube")
def youtube():
return render_template("youtube.html")
Notice the content security policy:
csp = {
'default-src': '\'self\''
}
This will force all content to come from the same origin as the application. Note that the default-src
policy directive is a fallback for other resource types when they don't have policies of their own (for more info on that click here).
Next, let's create the template we need for the /youtube
route and embed a youtube video in it:
templates/youtube.html
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/eoTpdTU8nTA"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen>
</iframe>
Now, let's run the application using flask run --debug
and navigate to /youtube
:
The embedded video is not shown by the browser. If you open dev tools, you will see the error below:
On the network tab, take a look at the response headers and notice the Content-Security-Policy
header:
To fix this, we will change our CSP in app.py
to allow content from Youtube:
csp = {
'default-src': ['\'self\'', 'https://www.youtube.com']
}
Now, run the app again, and navigate to /youtube
and you can see that the video renders successfully as below:
If you see the response headers for this request on the network tab, you will see that the Content-Security-Policy
header has changed as well:
Summary
We took a look at the basics of content security policies and for demonstration, we wrote a simple application using Python Flask.
Thanks for reading and I hope you found this article useful.
Subscribe to my newsletter
Read articles from Rohan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Rohan
Rohan
Software engineer and blogger