1. Bypassing Required Navigation
1.1. Problem
If navigation between protected areas of your web application is easily
predictable and weakly enforced, it may be possible to skip some
protections by directly requesting pages out of order. This recipe
demonstrates how to predict navigation and then attempt to bypass
it.
1.2. Solution
By far, the easiest way to predict navigation is to follow the
required course, then go back and use what you have learned to skip a
step. For instance, imagine a shopping cart system that uses the
following URLs in sequence:
http://www.example.com/checkOut/verifyAddress.asp
http://www.example.com/checkOut/verifyBilling.asp
http://www.example.com/checkOut/submitPayment.asp
http://www.example.com/checkOut/confirmPayment.asp
http://www.example.com/checkOut/confirmOrder.asp
What happens if a user pastes in the confirmOrder.asp URL immediately after
verifying their address? If the sequence of the order were weakly
enforced and poorly validated, conceivably the order would be shipping
without ever having been paid for!
In order to discover this weakness, all one must do is place a
valid order, record the appropriate URLs, and use this information the
next time to navigate to an out-of-sequence URL.
1.3. Discussion
While the example above is somewhat trivial, this particular
vulnerability is quite common. Another variation on this theme is to
include parameters in the URL that indicate the current state of the process.
If you see a URL like http://www.example.com/download.jsp?step=1&auth=false,
you should consider what happens if you change that to http://www.example.com/download.jsp?step=5&auth=true.
Many software-download websites try to force users to enter a name and
email address before downloading free or trial versions of software.
Very often a quick glance at the HTML source will tell you where the
download link is. You can directly browse to that link without entering
a name or email address.
There are many ways to prevent this vulnerability, such as using
formal authentication or authorization, or just keeping a checklist of visited
pages in session data. The difficult part is identifying a sequence as
required and what the various paths are. As these paths are essentially
state information about the user, state transition diagrams can be particularly helpful
during test design.
You may be familiar with state transition diagrams from software
development. Traditionally, state
transition diagrams formalize the legitimate pathways through the
system. By following a few valid paths, one can test many states
sequentially. However, in this case you should use the state transition
diagram to identify and attempt the invalid transitions. This removes
the efficiencies normally associated with state transition test design,
but still helps identify good security tests.
While predictable IDs represent the majority of cases, there are
other forms of unprotected predictable navigation. The most classic
example is perhaps the default administrator account. Many software packages are
shipped with a default administrator account, accessible via an admin
page with a default password. Do not let default admin pages remain
exposed without a custom password (and perhaps not even then)! The
default admin password will usually be specified in the documentation
for all to see. This example is so well known that it’s become something
of a cliché, but a quick Google query reveals that many, many
applications still expose admin pages (http://www.google.com/search?q=intitle). The lesson here
is: when using software packages, always check to ensure that the
passwords and settings have been changed from the default or that the
defaults are built to be secure.
At a major university, the Psychology 101 course was extremely
popular with as many as 500 or more students enrolled in any given
semester. The professor and teaching assistants found it cumbersome to
proctor and grade exams for so many students, so they built an online
exam system. Exams could be taken in computer labs, scored
immediately, and the grades could be more easily tracked and
curved.
Each exam required the student to answer all the questions, then
it showed the student her score and ultimately revealed the questions
she got wrong—along with the correct answers. The online exam system
allowed students to take previous years’ exams from home, just like
proctored exams, except they could be taken by anyone at any
time.
While taking a practice exam, one student discovered that you
could skip to the answer page prior to submitting the questions! While
the page indicated that the student got every answer wrong, it clearly
displayed the correct answers. Using this information, the student
could then go back to the question portion of the exam and submit the
correct answers. The proctored exams fell prey to this technique as
well.
Rather than face these sorts of issues, the professor decided to
scrap all online exams and resort to pencil and paper—and video record
the entire lecture hall during tests.
One dilemma here is that HTTP is inherently stateless; you
cannot depend on HTTP alone for information on what the user has done.
The advent of links makes it easy to design navigable paths through an
application. Yet it’s just as easy to navigate to a page even if a
link isn’t explicitly provided—nobody has to obey the suggested route
unless programmatically enforced.
2. Attempting Privileged Operations
2.1. Problem
Privileged or administrative features need to be protected from general
use. In order to ensure that such features are protected by a basic
level of authentication, this recipe walks you through a simple attempt
at privilege escalation.
2.2. Solution
Log in as an administrator or user with special privileges.
Navigate to a page that requires these privileges, containing links or
forms that trigger actions that only such special users can perform.
Copy the current URL as well as the links for each of these actions. If
the page contains forms, try saving the page to your local machine in
order to capture them. With this data in hand, log out of your
privileged user role and log in as a regular user or guest. For each URL
and link, paste the link into your address bar. If the page is
accessible and allows a regular user account or guest to perform
privileged operations, you’ve identified a privilege escalation
issue.
For form submissions, edit the local copy of the saved form to
ensure that the form action directs to your test server rather than your
local machine. For example, if the form used a relative path of
"formSubmit/submit.php" then
you’d need to append the URL you noted first, such as
"http://www.example.com/your_application/"
to it, to become action="http://www.example.com/your_application/formSubmit/submit.php".
After you’ve logged in as a regular or guest user, submit this
form from your local machine to your web application. If it triggers the
same action as it would for an administrator, this would be a privilege
escalation issue.
2.3. Discussion
You’re not always just defending from unauthenticated attackers.
The most sophisticated attacks will come from within. Your own users
will know your application better than anyone else and already have a
level of authentication beyond a guest. You don’t need many users before
one will start poking around, attempting common attacks.
The test described above looks for vertical privilege escalation, which is trying to get a
higher level of access than intended. Another variant of this test
identifies horizontal privilege escalation, which is accessing another
similar users account. Instead of using a URL with administrator
privileges, use a URL with another user’s query parameters. If by
pasting a URL containing certain identifiers you are able to access
another user’s account, you’ve found a horizontal privilege escalation
issue.
This kind of testing, where you login as one user and paste his
URL into another user’s session, seems pretty straightforward. Is it
really remarkable? It turns out that most commercial, automated web test
tools do not test very effectively for these sorts of issues. By adding
either manual or automated tests of this sort to your test process, you
will be performing tests that you cannot get from software that costs
tens of thousands of dollars.
3. Abusing Password Recovery
3.1. Problem
If your application has a password recovery feature, you need to
examine it for the kinds of data it might leak about your users or for
vulnerabilities that cause security failures.
3.2. Solution
There are several types of password recovery mechanisms, but they
generally fall into three categories:
Personal secret
When registering, the application will record several
verification facts. These typically include obscure details of
one’s life history—such as the name of one’s high school or make
and model of one’s car. This secret serves as a backup password
(one that is not likely to be forgotten).
Email recovery
The unique identity and access provided by an email account
serve as an alternative way to contact a person and thus verify
their identity. This method depends on the security and privacy of
an email address.
Administrated recovery
The user, upon forgetting the password, is prompted to contact
an administrator. Whether by phone, email, or even in person—the
administrator is responsible for verifying the user’s identity
prior to password recovery.
Each of these methods has strengths and weaknesses. Administrated
recovery is the most difficult to hack anonymously or remotely. However,
it has long been revealed that people are often the weakest link in a
security setup. Social engineering can go a long way. Email recovery is
also difficult to crack, although arguably less secure than the real
human contact of administrated recovery. Email accounts are rarely truly
secure; to depend on email for password recovery means relying upon a
third party for security.
This leaves the personal secret as the most-likely-to-be-hacked
password recovery mechanism. There is the case where a particular user
is targeted (and thus the attacker can learn the mother’s maiden name,
name of first significant other, or other “secret” information).
However, this is impossible to test.
If your application includes a personal secret password recovery
mechanism, you must ensure that the personal secrets are somehow more
secure than the password itself! These personal secrets will generally
not include numerals or special characters—as passwords often do. They
will likely be short, common names or phrases. These attributes make
them very easy to attack.
For example, if your application allows you three chances to
answer a security question to verify identity and that question happens
to be “What was the make and model of your first car?”, then you may be
vulnerable to a basic dictionary attack. There are a very limited number of
vehicle models sold—and even in this set, an attacker would attempt the
most popular models first. Given the sales trends in the United States
for the last 10 years or so, one could attempt “Toyota Camry,” then
“Toyota Corolla,” and finally “Honda Civic.” These three cars cover a
good 10–15% of the American population. If one was able to try this
attack against 1,000 or so user accounts, it is certain that a number of
accounts would be compromised.
3.3. Discussion
This attack is essentially the same as attempting a great number
of passwords, just with a different form of user authentication.
Standard practice is to record several personal secrets, and then prompt
the user for three of them during password recovery. This does help
reduce the chances of infiltration, but does not completely remove it.
Consider the following three questions:
What was your mother’s maiden name?
What was the name of your first childhood pet?
What was the name of your first significant other?
Because names are not distributed randomly, there is a very high
chance of one of these questions being the most common name in that
type. For example, an attacker could try “Smith,” “Rosie,” and “Emily.”
These are statistically common names for each of these questions. Asking
three questions does reduce the chance of any one attack getting
through. If the odds were 10% for a single question, the odds here are
closer to 0.1%. Still, given enough accounts to try, that represents the
potential to access a few accounts per thousand attempts.
Defense against these dictionary attacks is relatively
straightforward. By the time an attacker is attempting thousands of
combinations, significant processing power is required. This is not
going to be a manual process—an attacker will automate it. There are
many methods of defense, but one of the most popular is CAPTCHA (http://captcha.net/). It
tries to force the user to enter letters that they see on the screen to
prove that they are a human, as opposed to an automated computer
program. The images that are displayed are specially designed to be hard
for computers to decipher, but easy enough for a human.