computer 版 (精华区)
发信人: random (1 list per day), 信区: program
标 题: JSP Security
发信站: 听涛站 (2001年10月20日16:12:41 星期六), 站内信件
down from java.sun.com
The author offers a concise overview of code and configuration-level securi
ty issues that commonly arise in Java Server Pages scripts.
Introduction
Network programming has the sad and calamitous property that the overall sec
urity of the affected systems declines exponentially as the convenience and
power factors are increased. Incidentally, the various dynamic content gener
ation environments powering the World Wide Web are intended and designed pre
cisely to provide more power to developers and greater convenience for end-u
sers. Security is thus an aspect that must be explicitly factored in by the
system architects and developers, and is rarely effective as an afterthought
.
The weakest parts of server-side WWW applications, from a security perspecti
ve, are inherently the various interaction facilities and afferent channels.
These are the immediate means by which adversaries can affect the system, a
nd are invariably subjected to stress during attempts to identify and exploi
t vulnerabilities. The universal defense strategy against all related attack
s is known as input validation.
On a parallel level, security exposures are direct consequences of two main
design errors:
poor access control, and
implied assumptions about the deployment environment.
There are many extensive treatments of access control issues in the security
literature. Here we will discuss the problem of trust management on the low
implementation level (code and configuration), as pertaining to the Java Se
rver Pages environment. Accordingly, we will explain the ways in which malic
ious user input can manifest itself and alter the intended behavior of an ap
plication, and we will consider methods to validate input and reduce undesir
able exposure of information and programming interfaces.
Brief Overview of JSP
The Java Server Pages technology facilitates the creation and management of
dynamic WWW content by embedding Java coded logic inside HTML and XML docume
nts. The pages are preprocessed and converted to Java servlets by the JSP en
gine. Subsequent requests for the pages result in the Web server responding
with the output produced by the corresponding servlets. Although they are fu
nctionally equivalent, JSP represents a reversed approach to dynamic content
generation as compared to Java servlets in that the focus is on documents w
ith embedded Java code instead of applications with embedded HTML. JSP provi
des additional HTML-like tags to interact with JavaBeans components for exte
rnal functionality and access to reusable objects. A noteworthy characterist
ic of the JSP syntax is that although the HTML syntax is a subset of it (a p
ure HTML page is a valid JSP page), the reverse is not necessarily true. In
particular, JSP allows the embedding of tags within other tags as to facilit
ate dynamic generation of format as well as content. The following example i
s a valid JSP construct:
<A HREF = "<%= request.getRemoteUser() %>">
As we will see later, this introduces additional complications from a securi
ty point of view.
In comparison to the CGI protocol, JSP offers improved performance and sessi
on management (persistent states). This is achieved primarily by using Java
threads to handle multiple servlets running inside only one process (which i
mplements a JVM), whereas CGI scripts generally require the creation and des
truction of a process for each request.
Security Issues
By the sheer virtue of providing access to resources on a server, insecure J
ava servlets derived from JSP pages can put at risk any or all of the server
, the network on which this server resides, the clients accessing the pages,
and through possible DDoS and worm distribution attacks, the entire Interne
t. It is often assumed that Java, being the strong-typed, garbage collecting
, sandboxable language that it is, magically makes software secure. And inde
ed, many low-level security issues that are problematic in other languages,
such as buffer and heap overflows, are less of a peril in Java. This of cour
se does not mean that writing insecure Java is difficult, especially not whe
n writing servlets. Validating input and controlling access to resources alw
ays need to be considered. Furthermore, JSP is a fairly complex architecture
, in which many components come together. The interactions between them are
often sources of security breaches. And on top of that, although all existin
g JSP implementations are built around Java, the JSP specification allows vi
rtually any other language to play this role. The security aspects of the su
bstitute language then must also be taken in consideration.
In short, there are plenty of opportunities for introducing vulnerabilities
in a JSP system. We will review the most common of them below.
The General Problem of Untrusted User Input
Untrusted user input is, in practice, all user input. It originates from the
client but can reach the server through many different channels, and someti
mes under disguise. Some source of user input for a JSP server include, but
are not limited to:
the parameter string portion of the request URL,
data submitted by HTML forms through POST or GET requests,
data temporarily stored in the client browser (a.k.a. cookies),
queries to databases,
environment variables set by other processes.
The problem with user input is that it can be interpreted by the server-side
applications and thus an attacker can craft the incoming data so as to cont
rol some vulnerable aspect of the server. These vulnerabilities often manife
st themselves as points of access to data identified by user-supplied qualif
iers, or through execution of external functionality.
Naturally, JSP can make calls to native code stored in libraries (through JN
I) and execute external commands. The class Runtime provides the exec() meth
od which interprets its first argument as a command line to execute in a sep
arate process. If parts of this string must be derived from user input, this
input must first be filtered to ensure that only the intended commands are
executed, with only the intended arguments. Even if the command string does
not related to user input in any way, the execution of external commands mus
t still be done with due diligence. It is possible under certain circumstanc
es for an attacker to modify environment variables in the server environment
and in this way to affect the execution of external commands, for example b
y changing the PATH variable to point to a malicious program disguised under
the name of the program called by Runtime's exec(). To avoid this risk it i
s advisable to always set the environment explicitly before making external
calls. This can be done by providing an array of environment variables as th
e second argument to exec(). The variables in this array must have the forma
t name=value.
A similar problem arises when user input is used to identify any kind of inp
ut or output stream that the program opens. Access to files, databases, or o
ther network connections must not depend on unvalidated user input. Furtherm
ore, once a stream is open, it rarely safe to directly send user input to it
. This is especially true for SQL queries. The following JSP construct acces
sing the JDBC API is highly insecure, since an attacker can embed command se
paration characters in the submitted input and thus execute unwanted command
s on the SQL server:
<%@ page import="java.sql.*" %>
<!-- Some code here to open a SQL connection -->
<%
Statement stmt = connection.getStatement();
String query = "SELECT * FROM USER_RECORDS WHERE USER = " +
request.getParameter("username");
ResultSet result = Statement.executeQuery(query);
%>
If username contains a semicolon for instance, as in
http://server/db.jsp?
username=joe;SELECT%20*%20FROM%20SYSTEM_RECORDS
the attacker can gain access to (or damage) parts of the database to which t
hey are not entitled (assuming the Web server has privileges to access these
parts). In the example attack above, some SQL servers will ignore the whole
query, but others will proceed to execute the two commands.
Mitigation of these problems is achieved through appropriate input validatio
n.
Input Validation
Input validation (when the term is used in a security context) consists of p
erforming syntactic and sometimes semantic checks on data derived from exter
nal (untrusted) sources, as those listed in the previous section. Depending
on the criticality of the application and other factors, the actions perform
ed as a result of input validation may be one or more of the following:
escaping unsafe syntactic elements,
replacing syntactic elements with safe ones,
canceling the use of the affected constructs,
reporting an error condition,
activating an IDS.
Input validation can be performed in one of two modes -- rejecting unsafe ch
aracters by enumerating them, or rejecting unsafe characters by defining the
m as the negation of a predefined set of safe characters. The two approaches
are known as negative and positive input filtering, respectively. In genera
l, it is simpler and much safer to perform positive input filtering, since i
t is often a non-trivial task to enumerate all characters that can possibly
be misinterpreted by the server-side application, the client browser, the We
b server and the operating system on which it executes.
See the section on Cross Site Scripting attacks for an example of input vali
dation meant to protect client browsers from misinterpreting maliciously sub
mitted input.
Sensitive Data in GET Requests and Cookies
The most trivial method for transferring request data from the client to the
server-side application is the GET request method, as defined in the CGI pr
otocol. In this method, the input data is appended to the request URL and is
represented in the form:
URL[?name=value[&name=value[&...]]]
This encoding is clearly unsuitable for transferring security sensitive info
rmation, since the full URL and the request string normally travel in clear
text over the communication channels and get logged on all intermediate rout
ers as well as on the server. When valuable information needs to be transmit
ted as part of the client request, the POST method should be used, with a su
itable encryption mechanism (e.g. over an SSL connection). From the point of
view of the JSP engine, which method is used is largely irrelevant -- both
methods are handled identically.
At some point of the development of the World Wide Web, Netscape introduced
the concept of a cookie -- a small piece of information the server stores on
the client side and later retrieves in order to maintain session state info
rmation or to track the actions of the client browser. JSP provides the addC
ookie() method of the response implicit object to set a cookie on the client
side, and the getCookie() method of the request object to retrieve the cont
ents of a cookie. Cookies are instances of the javax.servlet.http.Cookie cla
ss. A security exposure is created when sensitive information is stored in c
ookies, for two reasons. First, the whole content of the cookie is visible t
o the client, and second, although browsers normally do not provide this cap
ability, there is nothing to prevent a user from responding with an arbitrar
ily forged cookie.
In general, none of the information submitted by the client browser can be a
ssumed to be safe.
Cross Site Scripting
CERT Advisory CA-2000-02 describes the problem of malicious HTML tags embedd
ed in client Web requests. This is commonly known as "cross site scripting",
which is somewhat of a misnomer since it isn't just about scripting, and th
ere is nothing especially cross site about it, but the term has stuck from w
hen the issue was less well understood.
The attack usually consists of an ill-meaning user submitting client-side ex
ecutable scripts (e.g. JavaScript code) or vicious HTML (or XML) tags which
the JSP server then includes in a dynamically generated page. The attack may
be targeted against other clients, or less commonly, against the server. A
typical example of a cross site scripting attack can be seen on some discuss
ion group servers which allow users to include formatting tags in their post
s. Commonly abused tags are those that allow embedding of code inside a page
, such as <SCRIPT>, <OBJECT>, <APPLET>, and <EMBED>. Other tags can also be
dangerous -- in particular, the <FORM> tag can be used to trick visitors int
o revealing sensitive information. A request string containing malicious tag
s could look similar to this:
http://server/jsp_script.jsp?poster=evilhacker&
message=<SCRIPT>evil_code</SCRIPT>
Mitigation of the problem is of course achieved through input validation and
output filtering. It is very important to do this kind of input validation
on the server side and not using JavaScript for instance on the client side.
There is nothing to prevent the user from bypassing client-side validation
code.
Here is a sample segment for server-side validation of embedded tags:
<!-- HTML code up to here -->
<% String message = request.getParameter("message");
message = message.replace ('<','_');
message = message.replace ('>','_');
message = message.replace ('"','_');
message = message.replace (''','_');
message = message.replace ('%','_');
message = message.replace (';','_');
message = message.replace ('(','_');
message = message.replace (')','_');
message = message.replace ('&','_');
message = message.replace ('+','_'); %>
<p>
The message is:
<hr/>
<tt><%= message %></tt>
<hr/>
</p>
<!-- more HTML below -->
Since it is difficult to enumerate all meta-characters in HTML, the safer ap
proach is to do positive filtering, discarding (or escaping) everything exce
pt the explicitly allowed characters (e.g. [A-Za-z0-9]).
A Note on JavaBeans
JSP uses a set of conventions described in the JavaBeans specification to ac
cess reusable components (Java objects) quickly and conveniently within a JS
P page. A Java Bean encapsulates data and functionality that can be used ind
ependent of the context in which it is called. A Bean contains data members
(properties) and implements a standardized API to access these properties th
rough getter and setter methods.
JSP provides a shorthand notation for initializing all JavaBeans properties
of a given Bean by matching name=value pairs in the query string which have
the same name as the desired property. Consider the following example of a u
se of a Bean (here we show the XML syntax):
<jsp:useBean id="myBasket" class="BasketBean">
<jsp:setProperty name="myBasket" property="*"/>
<jsp:useBean>
<html>
<head><title>Your Basket</title></head>
<body>
<p>
You have added the item
<jsp::getProperty name="myBasket" property="newItem"/>
to your basket.
<br/>
Your total is $
<jsp::getProperty name="myBasket" property="balance"/>
Proceed to <a href="checkout.jsp">checkout</a>
Notice the wild card notation (*) used in the setProperty method call. This
instructs JSP to set all properties of the Bean that have been specified in
the query string. The script is intended to be used as follows:
http://server/addToBasket.jsp?newItem=ITEM0105342
which will normally be constructed by an HTML form. The problem of course is
that there is nothing to prevent the user from setting the balance property
:
http://server/addToBasket.jsp?
newItem=ITEM0105342&balance=0
When processing the page's <jsp:setProperty> tag, the JSP container will map
this parameter to the Bean's like-named balance property, and attempt to se
t it to $0.
To prevent this, the JSP developer must implement safeguards in the Bean's g
etter and setter methods (the Bean must enforce access control to its proper
ties), and care must be taken when using the <jsp:setProperty> wild card.
Implementation Vulnerabilities and Source Code Disclosures
Certain versions of every JSP implementation have at some point shipped with
exposures that make the system vulnerable, even if the JSP developer follow
s secure programming practices. In a version of Allaire's JRun for example,
if the request URL contained the string .jsp%00 as part of the JSP script ex
tension, the server would not ignore the null byte and will assume that the
page is a static non-JSP page to be served as-is. The server will then make
a request to the operating system to open the page, at which point the null
byte will be ignored and as a result the source of the JSP page will be pres
ented instead of the results of its execution.
Similarly, a version of Tomcat had a vulnerability that would allow attacker
s to gain access to the JSP source by requesting the page as
http://server/page.js%2570
The trick here is that %25 is an URL encoded "%'', and 70 is the hexadecimal
value for "p''. The Web server does not invoke the JSP handler (since the U
RL does not end in ".jsp'') but the static file handler manages to map the U
RL into a correct filename (decoding the URL a second time).
Additionally, many Web servers and JSP implementations come packaged with sa
mple scripts which often contain vulnerabilities. It is safer to disable acc
ess to these scripts before the server is deployed in a hostile environment
(e.g. the Internet)
In short, JSP programmers must be aware of any current vulnerabilities in th
e platform for which they are developing. BUGTRAQ and any vendor-specific se
curity announcement lists are a good way too keep informed on such issues.
Conclusions
JSP, like any powerful technology, must be handled with care if secure and r
eliable operation of the deployed systems is to be assured. In this paper, w
e provided a concise overview of code and configuration-level security issue
s that commonly arise in JSP scripts, and offered advice for mitigation of t
he associated security risks.
--
记得到 progran 灌水啊!
※ 修改:·random 於 10月20日16:13:03 修改本文·[FROM: 匿名天使的家]
※ 来源:·听涛站 tingtao.dhs.org·[FROM: 匿名天使的家]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.529毫秒