Chapter 11 ■ the World Wide Web
201
For this sample application, you can take advantage of Flask’s built-in ability to digitally sign cookies so that they
cannot be forged. On a real production server, you would want to keep the signing key safely separated from your
source code, but for this example it can go near the top of the source file. Not only does including the key within the
source code for a production system reveal the key to anyone with access to your version control system, but it is also
likely to expose the credential to your developer laptops and your continuous integration process.
app.secret_key = 'saiGeij8AiS2ahleahMo5dahveixuV3J'
Flask will then use the secret key every time you set a cookie using its special session object, as during login.
session['username'] = username
session['csrf_token'] = uuid.uuid4().hex
And Flask will again use the key before trusting any cookie values that it pulls back out of the incoming request.
A cookie whose signature is not correct is assumed to be forged and treated as though it is simply not present in the
request at all.
username = session.get('username')
You will see these improvements in action in Listing 11-8.
Another worry with cookies is that they should never be passed over an unencrypted HTTP channel because
they will then be visible to everyone else on the same coffee shop wireless network. Many sites carefully set their
cookies using an HTTP-secured login page, only to expose them completely as the browser then pulls all of the CSS,
JavaScript, and images that are fetched over plain HTTP from the same hostname.
To prevent cookie exposure, find out how to make your web framework set the Secure parameter on every cookie
that you send to the browser. It will then be careful never to include it in unencrypted requests for resources that
everyone is allowed access to anyway.
Nonpersistent Cross-Site Scripting
If an opponent cannot steal or forge a cookie that will let their browser (or Python program) perform actions on behalf
of another user, then they can shift gears. If they can figure out how to take control of another user’s browser that is
logged in, then they will never even have to see the cookie. By performing actions with that browser, the cookie will
automatically be included in each request.
There are at least three well-known approaches to this kind of attack. The server in Listing 11-2 is vulnerable to all
three, and you are now going to learn about each of them in turn.
The first type is the nonpersistent version of cross-site scripting (XSS), where an attacker figures out how to make
a web site—like the example payment system—present attacker-written content as though it came from the site.
Imagine that the attacker wanted to send $110 to an account that they controlled. They might craft the JavaScript
shown in Listing 11-7.
Listing 11-7. Script attack.js for Making Payments