10.1. Session Management Attacks
HTTP is a stateless protocol. It was never designed to handle
sessions. Though this helped the Web take off, it presents a major
problem for web application designers. No one anticipated the Web
being used as an application platform. It would have been much better
to have session management built right into the HTTP standard. But
since it wasn't, it is now re-implemented by every
application separately. Cookies were designed to help with sessions
but they fall short of finishing the job.
10.1.1. Cookies
Cookies are a mechanism for web servers and web applications to
remember some information about a client. Prior to their invention,
there was no way to uniquely identify a client. The only other piece
of information that can be used for identification is the IP address.
Workstations on local networks often have static, routable IP
addresses that rarely change. These addresses can be used for pretty
reliable user tracking. But in most other situations, there are too
many unknowns to use IP addresses for identification:
Sometimes workstations are configured to retrieve an unused IP
address from a pool of addresses at boot time, usually using a DHCP
server. If users turn off their computers daily, their IP addresses
can (in theory) be different each day. Thus, an IP address used by
one workstation one day can be assigned to a different workstation
the next day. Some workstations are not allowed to access web content directly and
instead must do so through a web proxy (typically as a matter of
corporate policy). The IP address of the proxy is all that is visible
from the outside. Some workstations think they are accessing the Web directly, but
their traffic is being changed in real time by a device known as a
Network Address Translator (NAT). The address of
the NAT is all that is visible from the outside. Dial-up users and many DSL users regularly get assigned a different
IP address every time they connect to the Internet. Only a small
percentage of dial-up users have their own IP addresses. Some dial-up users (for example, those coming through AOL) can have a
different IP address on each HTTP request, as
their providers route their original requests through a cluster of
transparent HTTP proxies. Finally, some users do not want their IP addresses to be known. They
configure their clients to use so-called open proxies and route HTTP
requests through them. It is even possible to chain many proxies
together and route requests through all of them at once. Even in the case of a computer with a permanent real (routable) IP
address, many users could be using the same workstation. User
tracking via an IP address would, therefore, view all these users as
a single user.
Something had to be done to identify users. With stateful protocols,
you at least know the address of the client throughout the session.
To solve the problem for stateless protocols, people at Netscape
invented cookies. Perhaps Netscape engineers thought about fortune
cookies when they thought of the name. Here is how they work:
Upon first visit (first HTTP request), the site stores information
identifying a session into a cookie and sends the cookie to the
browser. The browser does not usually care about the content of a cookie
(there are some exceptions as we shall see later), but it will send
the cookie back to the site with every subsequent HTTP request. The site, upon receiving the cookie, retrieves the information out of
it and uses it for its operations.
There are two types of
cookies:
- Session cookies
-
Session cookies are sent from the server without an expiry date.
Because of that they will only last as long as the browser
application is open (the cookies are stored in memory). As soon as
the browser closes (the whole browser application, not just the
window that was used to access the site), the cookie disappears.
Session cookies are used to simulate per-session persistence and
create an illusion of a session. This is described in detail later in
this chapter.
- Persistent cookies
-
Persistent cookies are stored on disk and loaded every time the
browser starts. These cookies have an expiry date and exist until the
date is reached. They are used to store long-lived information about
the user. For example, low-risk applications can use such cookies to
recognize existing users and automatically log them in.
Cookies are transported using HTTP
headers. Web servers send cookies in a Set-Cookie
header. Clients return them in a Cookie header.
Newer versions of the standard introduce the names
Set-Cookie2 and Cookie2.
Clients normally send cookies back only to the servers where they
originated, or servers that share the same domain name (and are thus
assumed to be part of the same network).
To avoid DoS attacks by rogue web servers against browsers, some
limits are imposed by the cookie specification (for example, the
maximum length is limited and so is the total number of cookies).
Further information on cookies is available from:
10.1.2. Session Management Concepts
Session management is closely related to authentication, but while
session management is generally needed for authentication, the
relationship is not mandatory the other way around: sessions exist
even when the user is not authenticated. But the concept is similar:
When a client comes to the application for the first time (or, more
precisely, without having session information associated with it), a
new session is created. The application creates what is known as a session
token (or session ID) and sends it
back to the client. If the client includes the session token with every subsequent
request then the application can use its contents to match the
request to the session.
10.1.3. Keeping in Touch with Clients
There are three ways to implement sessions:
- Cookies
-
For sessions to exist, a piece of information must be forwarded back
and forth between the server and a client, and cookies were designed
for that purpose. Using a cookie is easy: programmers simply need to
pick a name for the cookie and store the session token inside.
- Extra page parameter
-
With this approach, every page is changed to include an additional
parameter. The parameter contains a session token. Receiving such a
parameter is easy. What is more complicated is ensuring every link in
the page contains it. One way to do it is to programmatically
construct every link (for GET requests) and every
form (for POST requests). This is difficult.
Another way is to have a page post-processing phase: when the page
construction is completed, a script locates all links and forms and
makes changes to include the session token. This is easier but does
not always work. For example, if a link is generated in JavaScript
code, the post-processor will not detect it to add the session token.
- Embedding the session token into the URL
-
You can have the application embed the session token into the URL.
For example, /view.php becomes something like
/view.php/3f9hba3578faf3c983/. The beauty of
this approach (for programmers) is that it does not require
additional effort to make it work. A small piece of code strips out
the session token before individual page processing starts, and the
programmer is not even aware of how the session management works.
Cookies are by far the simplest mechanism to implement sessions and
should always be used as a first choice. The other two mechanisms
should be used as alternatives in cases where the
user's application does not support cookies (or the
user does not accept cookies).
10.1.4. Session Tokens
Session tokens can be considered temporary passwords. As with all
passwords, they must be difficult to guess or the whole session
management scheme will collapse. Ideal session tokens should have the
following characteristics:
The reasons for these requirements will become clear once we start to
discuss different ways of breaking session management.
10.1.5. Session Attacks
Attacks against session management are popular because of the high
possible gain. Once an attacker learns a session token, he gets
instant access to the application with the privileges of the user
whose session token he stole.
10.1.5.1 Session hijacking
There are many ways to attempt to steal session tokens:
- Communication interception
-
When the communication channel is not secure, then no information is
safe, session tokens included. The danger of someone tapping into the
local traffic to retrieve session tokens is likely when applications
are used internally and there is a large concentration of users on
the same LAN.
- Involuntary token leak
-
URL-based session management techniques are vulnerable in many ways.
Someone looking over a shoulder could memorize or write down the
session token and then resume the session from somewhere else.
- Voluntary token leak
-
Another issue with URL-based session management techniques is that
session tokens can leak. Sometimes users themselves do it by copying
a page URL into an email or to a message board.
- Token leak through the Referer request header
-
As you may be aware, the Referer request header
field contains the URL of the page from which a link was followed to
the current page. If that URL contains a session token and the user
is making a jump to another (likely untrusted) site, the
administrator of that web site will be able to strip the session
token from access logs. Direct all external links to go through an
intermediary internal script to prevent tokens from leaking this way.
- Session fixation
-
Session tokens are created when they do not exist. But it is also
possible for an attacker to create a session first and then send
someone else a link with the session token embedded in it. The second
person would assume the session, possibly performing authentication
to establish trust, with the attacker knowing the session token all
along. For more information, read the paper by Mitja Kolsek, of ACROS
Security, entitled "Session Fixation Vulnerability
in Web-based Applications" (http://www.acros.si/papers/session_fixation.pdf).
- Cross-site scripting attacks
-
Cross-site scripting attacks (XSS) are the favorite methods of
stealing a session token from a client. By injecting a small piece of
code into the victim's browser, the session token
can be delivered to the attacker. (XSS attacks are explained in the
Section 10.6.2 later in this chapter.)
10.1.5.2 Brute-force attacks
If all else fails, an attacker can attempt to brute-force his way
into an application. Applications will generate a new token if you do
not supply one, and they typically completely fail to monitor
brute-force attacks. An automated script can, in theory, work for
days until it produces results.
The use of a flawed session token generation algorithm can
dramatically shorten the time needed to brute-force a session.
Excellent coverage of session brute-force attacks is provided in the
following paper:
- "Brute-Force Exploitation of Web Application Session Ids" by David Endler (iDEFENSE Labs) (http://www.blackhat.com/presentations/bh-usa-02/endler/iDEFENSE%20SessionIDs.pdf)
As a young web developer, I once designed a flawed session management
scheme. It used consecutive integer numbers for session tokens,
making session hijacking trivial (well, not quite, since some other
attributes of my scheme prevented hijacking, but the story sounds
better when I do not mention them). Here is what an attacker could
have done:
|
Typical session token problems include:
Tokens are short and can be cycled through easily. Sequential session tokens are used. Token values start repeating quickly. Token generation is based on other predictable information, such as
an IP address or time of session creation.
10.1.6. Good Practices
To conclude the discussion about session management, here are some
best practices to demonstrate that a robust scheme requires serious
thinking:
Create a session token upon first visit. When performing authentication, destroy the old session and create a
new one. Limit session lifetime to a short period (a few hours). Destroy inactive sessions regularly. Destroy sessions after users log out. Ask users to re-authenticate before an important task is performed
(e.g., an order is placed). Do not use the same session for a non-SSL part of the site as for the
SSL part of the site because non-SSL traffic can be intercepted and
the session token obtained from it. Treat them as two different
servers. If cookies are used to transport session tokens in an SSL
application, they should be marked
"secure." Secure cookies are never
sent over a non-SSL connection. Regenerate session tokens from time to time. Monitor client parameters (IP address, the
User-Agent request header) and send warnings to
the error log when they change. Some information (e.g., the contents
of the User-Agent header) should not change for
the lifetime of a session. Invalidate the session if it does. If you know where your users are coming from, attach each session to
a single IP address, and do not allow the address to change. If you can, do not accept users coming through web proxies. This will
be difficult to do for most public sites but easier for internal
applications. If you can, do not accept users coming through
open web proxies. Open proxies are used when
users want to stay anonymous or otherwise hide their tracks. You can
detect which proxies are open by extracting the IP address of the
proxy from each proxied request and having a script automatically
test whether the proxy is open or not. If you do allow web proxies, consider using Java applets or Flash
movies (probably a better choice since such movies can pretend to be
regular animations) to detect the users' real IP
addresses. It's a long shot but may work in some
cases.
An excellent overview of the problems of session management is
available in the following paper:
- "Web Based Session Management: Best practices in managing HTTP Based Client Sessions" by Gunter Ollmann (http://www.technicalinfo.net/papers/WebBasedSessionManagement.html)
|