A1.1 Description
Web applications use input from HTTP requests (and
occasionally files) to determine how to respond. Attackers can tamper
with any part of an HTTP request, including the url, querystring,
headers, cookies, form fields, and hidden fields, to try to bypass
the site's security mechanisms. Common names for common input
tampering attacks include: forced browsing, command insertion, cross
site scripting, buffer overflows, format string attacks, SQL
injection, cookie poisoning, and hidden field manipulation. Each of
these attack types is described in more detail later in this paper.
Some sites attempt to protect themselves by
filtering out malicious input. The problem is that there are so many
different ways of encoding information. Since almost all HTTP input
can be represented in multiple formats, unusual encodings can be used
to obfuscate any attack targeting the vulnerabilities described in
this document. This makes filtering very difficult. To protect
themselves, web applications should convert input parameters to the
simplest form before they are validated, otherwise, malicious input
can be masked and slip past filters. The process of simplifying these
encodings is called "canonicalization."
A surprising number of web applications use only
client-side mechanisms to validate input. Client side validation
mechanisms are easily bypassed, leaving the web application without
any protection against malicious parameters. Attackers can generate
their own HTTP requests using tools as simple as telnet. They do not
have to pay attention to anything that the developer intended to
happen on the client side. Client side validation is a fine idea for
performance and usability, but it has no security benefit whatsoever.
Server side checks are required to defend against parameter
manipulation attacks. Once these are in place, client side checking
can also be included to enhance the user experience for legitimate
users and/or reduce the amount of invalid traffic to the server.
These attacks are becoming increasingly likely as
the number of tools that support parameter "fuzzing", corruption,
and brute forcing grows. The impact of using unvalidated input should
not be underestimated. A huge number of attacks would become
difficult or impossible if developers would simply validate input
before using it. Unless a web application has a strong, centralized
mechanism for validating all input from HTTP requests (and any other
sources), vulnerabilities based on malicious input are very likely to
exist.
A1.2 Environments Affected
All web servers, application servers, and web
application environments are susceptible to parameter tampering.
The
following table lists some of the available tools for checking for
unvalidated input across different development platforms.
|
Platform
|
Available
Tools
|
|
PHP
|
Safe
Mode - Protects against individual users setting dangerous
configuration values.
Error
Reporting - Setting error reporting to E_ALL will warn
against using variables that have not been initialized or checked.
Register
Globals - As of PHP 4.2.0, the default value for
register_globals is off. This prevents the injection of values
into variables through querystring or form values through global
registration.
|
|
ASP.NET
|
ValidateRequest
Page Directive - By default, the ValidateRequest page
directive is set to true. This causes an exception to be thrown
if user input matches a list of potentially dangerous values.
This protects against many XSS type attacks.
Strong
Typing - Variables used in the ASP.NET page or in
code-behind files are strongly typed. Explicit casting can be
enforced by using the Strict option in VB.NET and is always
enforced in other .NET languages.
|
|
J2EE
|
Stinger
- Stinger is an HTTP Validation Engine developed by OWASP. It
checks input against a configurable set of potential threats.
This product may become available for other development
environments.
Strong
Typing - Java is a strongly typed language, requiring
stricter coding than in a loosely typed language.
|
|
Perl
|
Taint
- Taint marks variables originating from the user or the execution environment as "tainted" during program
operation and causes a taint violation if the tainted data is used
in operations which could be potentially dangerous.
|
A1.3 Examples and References
A1.4 How to Determine If You Are Vulnerable
Any part of an HTTP request that is used by a web
application without being carefully validated is known as a "tainted"
parameter. The simplest way to find tainted parameter use is to have
a detailed code review, searching for all the calls where information
is extracted from an HTTP request. For example, in a J2EE
application, these are the methods in the HttpServletRequest class.
Then you can follow the code to see where that variable gets used. If
the variable is not checked before it is used, there is very likely a
problem. In Perl, you should consider using the "taint" (-T)
option.
It is also possible to find tainted parameter use
by using tools like OWASP's WebScarab. By submitting unexpected
values in HTTP requests and viewing the web application's
responses, you can identify places where tainted parameters are used.
Specific examples include:
Global Variables Exploit in PHP with Post and Get - If PHP is configured
with "set globals on" (the default setting previous to version 4.3),
application variables can be initialized via an HTTP request. An
application may be vunerable to unexpected values passed by the user.
Cross-site Scripting - See section A4
SQL Injection - use variable binding if possible when executing queries.
Otherwise, escape all strings and treat integers as strings by enclosing
them in quotes.
URL manipulation - Validate URLs that are entered in forms.
Embedded commands in echoed data - Encode HTML special characters
before echoing them back to the browser.
A1.5 How to Protect Yourself
The best way to prevent parameter tampering is to
ensure that all parameters are validated before they are used. A
centralized component or library is likely to be the most effective,
as the code performing the checking should all be in one place. Each
parameter should be checked against a strict format that specifies
exactly what input will be allowed. "Negative" approaches that
involve filtering out certain bad input or approaches that rely on
signatures are not likely to be effective and may be difficult to
maintain.
Parameters should be validated against a
"positive" specification that defines:
Data type (string, integer, real, etc...)
Allowed character set
Minimum and maximum length
Whether null is allowed
Whether the parameter is required or not
Whether duplicates are allowed
Numeric range
Specific legal values (enumeration)
Specific patterns (regular expressions)
A new class of security devices known as web
application firewalls can provide some parameter validation services.
However, in order for them to be effective, the device must be
configured with a strict definition of what is valid for each
parameter for your site. This includes properly protecting all types
of input from the HTTP request, including URLs, forms, cookies,
querystrings, hidden fields, and parameters.
The OWASP Filters project is producing reusable
components in several languages to help prevent many forms of
parameter tampering. The Stinger HTTP request validation engine
(http://www.aspectsecurity.com/stinger/
) was also developed by OWASP for J2EE environments.