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.