Chapter 11 ■ the World Wide Web
206
As I write this, the Shellshock vulnerability has just been announced: for the past 22 years, without anyone
noticing, the widely used Bash shell has been willing to run any code presented to it as specially formatted
environment variables—like those that the old CGI mechanism will happily set based on incoming untrusted HTTP
headers. If major production software can be vulnerable to unexpected features and interactions after more than
two decades, it is hard to make promises about the absolute security of a demonstration web application that I wrote
solely for this chapter.
But here is the listing. Its templates do proper escaping, it uses internal storage for flash messages instead of
sending them round-trip through the user’s browser, and a hidden random UUID in each form it presents to the user
makes them impossible to forge.
Note that two of the major improvements—switching to internally stored flash messages and asking Jinja2 to do
proper escaping of characters before adding them to the HTML—have come about by using standard mechanisms
already built into Flask instead of relying on my own code.
This illustrates an important point. Not only will your applications often be shorter, more concise, and more
convenient to write if you read framework documentation thoroughly and lean on as many of its features as you can,
but it will often be more secure because you will be using patterns written by a professional and carefully improved
by the web framework’s entire community. In many cases, these conveniences will address security or performance
problems of which you might not even be aware.
The application is now fairly well automated when it comes to its interaction with the network. But there are still
many seams showing when it comes to the handling of views and forms.
The code has to check manually whether the user is logged in. Each form field needs to be copied manually
from the request into the HTML so that the user does not need to retype it. And the conversation with the database is
disappointingly low-level; you must open database sessions yourself and then remember to commit if you want the
payment to be recorded permanently by SQLite.
There are good best practices and third-party tools in the Flask community to which you could turn to address
these common patterns. But instead, for variety, the last example will be the same application written in a framework
that takes more of these responsibilities away from you from day 1.
The Payments Application in Django
The Django web framework is probably the most popular among Python programmers today because it is a “full-stack”
web framework that comes with everything built in that a novice programmer needs. Not only does Django have a
templates system and URL routing framework, but it can also talk to the database for you, render the results as Python
objects, and even compose and interpret forms without needing a single third-party library. In a world where many
people programming for the Web have little training, a framework that establishes coherent and safe patterns can be
more valuable than a more flexible tool that sends the programmer hunting for their own ORM and forms library,
when they might not even have a clear idea about how those pieces fit together.
You can find the Django application in its entirety at the source code repository for this book. Again, here is the
URL for this chapter:
https://github.com/brandon-rhodes/fopnp/tree/m/py3/chapter11
There are several files of boilerplate that are not worth quoting in full here in the pages of this book.
• manage.py: This is an executable script sitting in the chapter11/ directory that lets you run
Django commands to set up and start the application in development mode, as you will see in
a moment.
• djbank/__init__.py: This is an empty file that tells Python that the directory is a Python
package from which modules can be loaded.
• djbank/admin.py: This contains three lines of code that make the Payment model appear in
the Admin interface, as described in the “Choosing a Web Framework” section that follows.