Chapter 11 ■ the World Wide Web
194
Not only is the listing dangerous, but it is also vulnerable to many of the most important attack vectors active on
the modern Web! By studying its shortcomings over the next few sections of this chapter, you will learn the minimum
armor that an application needs to survive. These weaknesses are all mistakes in its data processing, and are separate
from the question of whether the site has been properly protected with TLS against prying eyes in the first place. You
can go ahead and imagine that it is indeed protected by encryption, perhaps by a reverse proxy sitting in front of the
server (see Chapter 10), because I will be considering what an attacker could do even without being able to see data
passing between a particular user and the application.
The application uses the Flask web framework to take care of the basics of operating as a Python web application:
answering 404 for pages that the application does not define, parsing data from HTML forms (as you will learn in the
following sections), and making it easy to compose correct HTTP responses containing either HTML text from one
of its templates or a redirect to another URL. You can learn much more about Flask than will be mentioned in this
chapter by visiting its documentation at the http://flask.pocoo.org/ web site.
Imagine that programmers who are not familiar with the Web had put together this listing. They have heard of
template languages that make it easy to add their own text to HTML, so they figured out how to get Jinja2 loaded and
running. Furthermore, they discovered that the Flask micro-framework is second only to Django in popularity and,
liking the fact that a Flask application can fit in a single file, they have decided to try it.
Reading from top to bottom, you can see a login() page and a logout() page. Because this app has no real
user database, the login page simply hard-codes two possible user accounts and passwords. You will learn more
about form logic in a moment, but you can already see that the result of logging in and logging out is the creation
and deletion of a cookie (see Chapter 9 and Chapter 10) that, when present in subsequent requests, marks them as
belonging to a particular authenticated user.
The other two pages on the site protect themselves from unauthorized users both by looking for this cookie and
by redirecting back to the login page if they are unhappy with the lack of a value. The login() view has only two lines
of code (well, three because of line length) beyond the check for a logged-in user: it pulls the current user’s payments
from the database, and it puts them together with some other information to provide to the HTML page template.
That the page might want to know the username makes sense, but why does the code check the URL parameters
(which Flask makes available as a request.args dictionary) for a message named 'flash'?
The answer is apparent if you read the pay() page. In the case of a successful payment, the user will be redirected
to the index page but will probably want some indication that the form had its intended effect. This is provided by a
flash message, as web frameworks call them, displayed at the top of the page. (The name has nothing to do with the
old Adobe Flash system for writing ads, but it refers to the fact that the message is “flashed” in front of the user when a
page is next viewed and then disappears). In this first draft of the web application, the flash message is simply carried
as a query string in the URL.
http://example.com/?flash=Payment+successful
The rest of the pay() routine is a familiar dance to the readers of web applications: checking whether a form has
been submitted successfully and performing some action if it has. Because the user or browser might have provided
or omitted any of the form parameters, the code gingerly and cautiously looks for them with the get() method of the
request.form dictionary that can return a default (here, the empty string '') if a key is missing.
If the request is satisfactory, then the payment is added permanently to the database. Otherwise, the form is
presented to the user. If they have already done the work of typing in some information, then the code is careful not
to throw that work away: instead of presenting them with a blank form and error message that discards their work, it
passes the values they have typed back into the template so that they can be redisplayed.
Reviewing the three HTML templates mentioned in Listing 11-2 will be crucial to the next section’s discussion of
forms and methods. There are actually four templates, because the common design elements of the HTML have been
factored out into a base template, which is the most common pattern used by designers building multipage sites.
The template in Listing 11-3 defines a page skeleton with insertion points where other templates can insert a
page title and a page body. Note that the title can be used twice, once in the