Mashups are applications and Web pages built using an aggregation of UI artifacts and data from diverse and often public sources. A mashup development model introduces an open development model along with many new security risks. These new risks bring security to the forefront when developing a mashup application.
Traditional security measures such as DMZs and firewalls fall short when addressing the fine-grained access required for mashup UI artifacts and data. A mashup application or page must address such issues as cross-site request forgery (CSRF), Asynchronous JavaScript™ + XML (Ajax) vulnerabilities, cross-site scripting (XSS), and other potential security weaknesses.
This article explores security issues that you should address when building mashup applications and pages.
Mashup pages or applications are built using data and UI artifacts combined from one or more internal and external sites, typically in an ad hoc manner. This model of development leads to security vulnerabilities that can multiply very quickly: With each new artifact or data source added to a mashup, security vulnerabilities increase. Such open integration makes it essential to ensure that artifacts and data are tested and secured against malicious intrusions.
Mashup pages can also be used as components or data sources for other mashups, which makes predicting exactly how mashup artifacts, pages, and data sources will be used as time goes by difficult. Therefore, it is imperative that you address security in all components and processes used in a mashup.
Many intrusion vulnerabilities such as SQL injection, CSRF, and XSS are preventable using a comprehensive input-validation framework.
A mashup server-side validation framework and a client-side mashup validation framework should complement each other in the manner they process input data. Because client-side validation can be circumvented quite easily, a comprehensive and complementary server-side validation provides another crucial component for protecting data and processes.
For an input-validation framework to be effective, it should:
- Define a list of finite values to which input data should be constrained
- Validate input data types, data lengths, data ranges, and data formats
- Use regular expressions at the client and at the server to facilitate a consistent validation model
- Sanitize input data for invalid characters
Avoiding on-demand scripting exploits
One technique used in many mashups is to embed JavaScript snippets that are dynamically downloaded and interpreted on demand. On-demand scripts can include malicious code aimed at exploiting security vulnerabilities such as XSS. You can prevent this vulnerability by ensuring that on-demand scripts are validated and that content generated from the scripts is encoded properly to prevent execution of malicious code. Listing 1 provides an example of unencoded markup.
Listing 1. Example of unencoded markup
<div> This is example content </div> |
An encoded version of the preceding snippet is shown in Listing 2.
Listing 2. Example of encoded markup
<div>
This is example content
</div>
|
As shown above, mashup pages using scripts generated dynamically must ensure that the data the scripts generated is validated and encoded to avoid interpretation of the data by the browser as HTML markup or scripting code. This inadvertent interpretation can lead to malicious code execution and possible security violations.
Data that is not validated and encoded runs the risk of exploiting the following vulnerabilities:
- Compromised data integrity
- Intruders creating or accessing cookies
- Intruders intercepting and accessing user input
- Execution of malicious scripts within a trusted domain or context
An intelligent analysis of each context interpreted should be made so that only characters that could cause problems within each particular context are addressed.
Authenticating a user at the server without first invalidating existing sessions can lead to what is termed session fixation. Session fixation allows intruders to intercept authenticated sessions or to create new sessions and to capture the session identifier. The session identifier can then be used maliciously when a legitimate user creates a session with the same session identifier.
The Java™ code in Listing 3 illustrates authenticating a client request without first invalidating the existing session.
Listing 3. Example of a session fixation vulnerability
private boolean authenticateUser(HttpServletRequest req)
{
// session.invalidate() should have been called prior to this
// to invalidate an existing session
HttpSession session = req.getSession(false);
if (null != session)
{
// existing session assumed valid
return true;
}
if (authenticateRequest(req) == true)
{
// create a new session
req.getSession();
return true;
}
return false;
}
|
Listing 3 illustrates a situation in which an existing session has not been invalidated and is therefore assumed to be valid for the current request. This situation may be exploited when a new user provides authentication credentials to the server, which allows the originator of the existing session to record and possibly exploit data as long as the session is valid.
Techniques used to prevent this type of attack include:
- Specifying session timeouts
- Promoting session invalidation using explicit logout UI controls
- Forcing users to reenter credentials whenever privacy is essential
- Regenerating session identifiers with each request
This situation is often exploited by intruders in a mashup page in order to side-step browser restrictions and to redirect sensitive data that is then recorded. This attack is known as cross-site scripting.
CSRF attacks originate from malicious code from an intruder site that tricks a browser into transmitting unprovoked requests to a trusted site. A browser's same-origin policy (SOP) does not thwart requests being transmitted from a site of different origin, but only requests being transmitted to a site of different origin. Therefore, the SOP will not prevent CSRF attacks.
CSRF attacks depend on a server assuming that all requests transmitted from the browser that originally started an authenticated session are valid. Typical authentication mechanisms such as user name/password, cookies, and SSL certificates are not sufficient for protecting against CSRF attacks, because these mechanisms depend on authenticating sessions between a browser and the server, not between each individual request and the server.
During a CSRF attack, requests originate from an intruder site and are transmitted through an authenticated browser page to the server. Responses are then transmitted unknowingly back to the intruder site. The sequence of requests and responses during a CSRF attack is illustrated in Figure 1.
Figure 1. Sequence of events during a CSRF attack
Figure 1 shows an intruder site issuing requests to a mashup server through an authenticated mashup page. This attack is only possible if the intruder site gets the mashup page to proxy the requests to the corporate mashup server for the intruder site. This can occur with various HTML techniques.
One
technique intruders use to initiate a CSRF attack is to embed a URL within the
src attribute of an <img> tag. When the browser evaluates the <img> tag, the URL is referenced. Data can be passed to the
host that the URL references. For example, note the following <img> tag:
<img src="http://mybank/transfer?amount=10000&fromaccount=44332&toaccount=55443"> |
If
the page containing the <img> tag above is
visited while the session is authenticated to mybank, the <img> tag is evaluated and references the URL that the src attribute specifies, thereby instigating the
requested action.
You can prevent this type of CSRF attack if the
server at mybank avoids the use of HTTP GET
requests to initiate changes and, instead, uses only POST requests to initiate changes.
A technique for
preventing CSRF attacks that mashup servers often use is to require each HTTP
request to include a request-specific token to be transmitted to the server
with each POST and GET
request.
JavaScript Object Notation (JSON) is a data
construct that adheres to the syntax of the JavaScript programming language.
Therefore, JSON data can be processed by almost any standard JavaScript
function or statement. In particular, the eval()
function can be used and often is used to process JSON data.
Listing 4 is a simple example of a block of JSON data.
Listing 4. Example of a block of JSON data
[
{
name: "object1",
message: "Greetings from object1",
},
{
name: "object2",
message: "Greetings from object2"
},
{
name: "object3",
message: "Greetings from object3"
code: alert("This will be executed when evaluated!")
},
{
name: "object4",
message: "Greetings from object4"
},
{
name: "object5",
message: "Greetings from object5"
}
]
|
When
the JSON data illustrated above is evaluated, the JavaScript instructions
embedded in the object named object3 are executed.
This feature is often exploited by mashup servers and mashup applications to
use JSON as the data format for responses transmitted back from a server to
the browser for XMLHttpRequest object requests.
However, this mechanism also presents some significant security
vulnerabilities.
As stated above, any JavaScript instructions embedded
within a JSON data block are executed immediately as the data block is
interpreted. The JavaScript language's eval()
function is often used to process JSON data, as shown in the following
example:
var jsonObject = eval('(' + httpReqResponse + ')');
|
Instructions
embedded in a JSON data block and processed by the eval() function are executed immediately. If the data contains
malicious code, sensitive data on the mashup page can fall into the wrong
hands. Also, the malicious code can gain control of the mashup page.
There are several techniques for averting JSON data exploits, including:
- Preceding a block of JSON data with an endless
whileloop - Wrapping a block of JSON data in JavaScript comments
- Avoiding use of the
eval()function to process a block of JSON data
Listing 5 provides an example of preceding a block
of JSON data with a while(1); statement. When using
this technique, the while(1); statement must be
stripped at the client before using the JSON data to avoid an endless loop.
Listing 5. Example of a block of JSON data wrapped in a while loop
while(1);
[
{
name: "object1",
message: "Greetings from object1",
},
{
name: "object2",
message: "Greetings from object2"
},
{
name: "object3",
message: "Greetings from object3"
code: alert("This will be executed when evaluated!")
},
{
name: "object4",
message: "Greetings from object4"
},
{
name: "object5",
message: "Greetings from object5"
}
]
|
You
can use the JSON.parse() function that the JSON
libraries provide (see Resources) in place of the
standard eval() function. Listing
6 provides an example of processing JSON data with the use of the JSON.parse() function.
Listing 6. Example of the JSON.parse function
<script type="text/javascript" src="js/json2.js"></script> var jsonObject = JSON.parse(httpReqResponse); |
Listing 7 shows a block of JSON data wrapped between JavaScript comments. The comments must be stripped at the client before using the JSON data.
Listing 7. Example of a block of JSON data wrapped in JavaScript comments
/*
[
{
name: "object1",
message: "Greetings from object1",
},
{
name: "object2",
message: "Greetings from object2"
},
{
name: "object3",
message: "Greetings from object3"
code: alert("This will be executed when evaluated!")
},
{
name: "object4",
message: "Greetings from object4"
},
{
name: "object5",
message: "Greetings from object5"
}
]
*/
|
Mashup widgets are often embodied as embedded inline frames (iframes). iframes are HTML elements regarded as separate entities by a browser within a page. Because content placed inside an iframe cannot manipulate any part of a browser's DOM outside of the containing iframe, iframes are often used as mashup widgets and other UI artifacts to isolate potentially malicious content within a mashup page.
Listing 8 illustrates two typical iframe elements.
Listing 8. Example of typical iframe elements
<iframe src="http://jeffhanson.com/iframe1.html" /> <iframe src="http://jeffhanson.com/iframe2.html" /> |
An iframe is typically used as a visual element displayed in a browser page as a bordered UI component. However, iframes are often hidden and used as messaging controls within a browser page, as shown in Figure 2.
Figure 2. Data passing between an iframe and a mashup page
This figure shows an HTML page found at jeffhanson.com/index.html. A hidden
iframe is embedded within the page's DOM and constructed from content found at
jeffhanson.com/test.html. The JavaScript function sendData() sets the src URL for the
hidden iframe to http://jeffhanson.html#data. The part of the src URL following the fragment identifier (hash mark)
can be retrieved using the window.location.hash
element, as shown in the function defined for the onLoad event. Using this mechanism, the hidden iframe can retrieve
the data following the fragment identifier when the index.html page loads.
This technique is often used to transmit data between iframes or between HTML
pages and embedded iframes.
The iframe data-transmission mechanism
described above introduces security vulnerabilities. Because the src URL can be set by any component within the
containing HTML page, a UI artifact embedded in the page containing malicious
code can compromise the privacy of data contained within the page and can
potentially communicate with the server from which the main HTML page
originates.
You can use several techniques to prevent iframe fragment-identifier attacks:
- Ensure that only white-listed domains can modify fragment identifiers.
- Encrypt fragment-identifier data using public keys.
- Filter fragment-identifier data using JavaScript code.
- Restrict JavaScript code embedded in fragment-identifier data from being executed inadvertently.
Mashups are applications and Web pages constructed from UI artifacts and data from diverse and often public sources. A mashup development model operates within a very open environment that presents many new security risks. These new risks make security a top priority when developing a mashup application.
A mashup application or page must address CSRF, Ajax vulnerabilities, XSS, and other potential security weaknesses. Traditional security measures such as DMZs and firewalls fall short when addressing the security needs required for mashup development. This article discussed techniques for addressing security issues encountered when building mashup applications and pages.
Learn
- Check out the Enterprise Mashup
Implementations site for more information about mashups.
- To find out more about whether a mashup is
right for your needs, see the developerWorks article, "Choosing between mashups and traditional Web applications" (Holt Adams
and John Gerken, July 2008).
- To learn more about using JSON with mashups,
see the developerWorks article, "Combine
JSONP and jQuery to quickly build powerful mashups" (Seda
Özses and Salih Erqül, February 2009).
- The developerWorks Web
development zone is packed with tools and information for Web 2.0
development.
- My
developerWorks: Personalize your developerWorks experience.
Get products and technologies
- Find more
information about JSON, as well as the libraries you need, at JSON.org.
- Download IBM product evaluation versions and get your hands on application
development tools and middleware products from DB2®,
Lotus®, Rational®, Tivoli®, and
WebSphere®.
Jeff Hanson has more than 20 years of experience in the software industry, including working as senior engineer for the Microsoft® Windows® port of the OpenDoc project, lead architect for the Route 66 framework at Novell, and chief architect for eReinsure.com, Inc. Jeff is currently the CTO for Max International, where he directs design and implementation of enterprise applications and platforms for retail and wholesale industries. He is the author of numerous articles and books, including .NET versus J2EE Web Services: A Comparison of Approaches, Pro JMX: Java Management Extensions, Web Services Business Strategies and Architectures, and Mashups: Strategies for the Modern Enterprise. You can reach Jeff at jjeffreyhanson@gmail.com.



