WebAppers

/ best free open source web resources /

Shopify

Security of Mashup Applications for Enterprises

Posted · Category: Information

Beyond the buzz of Web 2.0, mashup applications (also called hybrid or situational applications) bring the promise of creating meaningful experiences by feeding other people’s data to your application. For businesses, this means consuming data without the overhead of infrastructure or data storage and being able to tap into established technology vendors such as Bing Maps, LinkedIn or Twitter. While combining components from all over the web can help you quickly build a powerful application, it can also expose your users to malicious content that sneaks into your application from your providers. How can you protect your users and still realize the potential of mashup applications for the enterprise?

In this series, I’ll investigate how to mitigate security issues that can come along with a mashup application. To frame the discussion, we’ll build an application for the fictional Vision Sciences Corporation, leveraging risk management, good-old input validation and the muscle of modern browsers to keep users safe. Each article will focus on one of these elements, starting in this article, where I’ll examine how modern browsers help isolate content. At the end of this article, you’ll understand how the browser is the first layer in your defense-in-depth strategy against malicious mashup madness.

What Are We Building?

I always find a sample project helpful to illustrate development issues. Talking about the sample lets me dive into a narrative, not just detached code. So to start, imagine the following scenario:

You are a developer at Vision Science Corporation, and your product team has requested that you build an HTML5 application for the company’s office locations around the world that shows news about health and safety risks combined with medical information distilled from Twitter.

Being a savvy developer, you know that you can get this data from a variety of sources in your organization and through external providers like Bing Maps and Twitter. Here is a breakdown of the data sources and systems for the application:

Internal Data

  • HR system for employee and facility information; XML output through ASP.NET pages from hr.visionsciences.com.
  • Physical security department’s intranet site for medical intelligence information; HTML content from security.visionsciences.com/med-intel.html.
  • Physical security department’s travel advisory system (REST API) from security.visionsciences.com/travel/.

External Data

  • Twitter API to collect local medical intelligence (aka crowd sourcing).
  • Bing Maps API to plot the facilities on a map.

Our First Challenge: Getting Data from Other Domains

To begin, we need to be on the same page about a critical concept that impacts mashup design, implementation and maintenance: same origin policy (SOP). Back in the days of Netscape (1995), when JavaScript and DOM were introduced, it was decided to restrict scripts from communicating with resources with a different protocol, host and port (known as the origin; see Michael Zalewski, Tangled Web, 2012). This policy restricts apps.visionsciences.com from accessing content on hr.visionsciences.com because the sites’ host names are different. As you can see, SOP is good for restricting unauthorized access, but it also restricts legitimate access. SOP impacts several browser features that enable mashup applications, such as web storage, cookies, XmlHttpRequests, and others. For example, if the following code block was run on apps.visionsciences.com, it could not reference the XML document requested from hr.visionsciences.com because the host name of the responder is different from the host name of the requestor.

// Script running on http://apps.visionsciences.com

$.ajax({

url: "http://hr.visionsciences.com/data.xml",

dataType: 'xml',

type: 'GET',

success: function (data) {

alert("Success!");

},

error: function (ex) {

alert(ex);

}

});

If you want to consume this data for your mashup, you have a problem and need to look at another solution. You could use a proxy design through which a server-side control consumes the data and then provides it through a local resource, or you could work with the data provider to cook up a JSONP execution. Both of these are decent solutions, but today’s web browsers offer another solution that can require less code and less development cost: cross-origin resource sharing (CORS).

SOP works well for isolated sites, but in a world where data can be anywhere, it becomes more of a hindrance to developers. Cross-origin resource sharing allows providers to make their content accessible by adding the Access-Control-Allow-Origin header to the response for their resource, but adding this header does not mean that anyone can access resources from the provider. By using the Access-Control-Allow-Origin header, providers can state which origins can access their data. As an example, here is the hr.visionsciences.com header:

Access-Control-Allow-Origin: http://apps.visionsciences.com

Now the previous Ajax request will work because the client and server are participating with each other on the request and response. But if you ran the same Ajax code from security.visionsciences.com it would fail because hr.visionsciences.com is only permitting requests from apps.visionsciences.com.

This approach creates a white list of permitted requestors, enabling only qualified requestors to receive content. For an instance when you want to provide the content to anyone requesting it, you can simply use an asterisk for the domain in the Access-Control-Allow-Origin header:

Access-Control-Allow-Origin: *

From a security perspective, please keep in mind that using an asterisk allows anyone to access your content. Your purpose and organization’s risk tolerance will drive how open (or closed) your implementation of CORS will be. If your organization wants to restrict access to data because of the data’s proprietary nature, stay away from * and maintain your white list with recurring (at least every six months) access reviews. Determine who is accessing your data, why they need access and if they should still have access.

While CORS makes life easier for data consumers, data providers can be taking on more risk. If you (as a data provider) permit more than read-only operations through your CORS implementation, you could be opening the door to a cross-site request forgery (CSRF) attack. Be selective in what returns the Access-Control-Allow-Origin header and limit it to data you want to provide via CORS. For example, do not include the header on resources like a settings information page or a password reset page. These resources are prime targets for CSRF attacks.

From a client-side perspective, not all browsers support CORS. Some browsers have supported it for a long time, while others are just now coming to the party. Depending on your enterprise’s standardized browser and version, you might need to consider a CORS alternative (like postMessage). Check out When can I use… to see if CORS is available for your organization’s choice of browser. Internet Explorer 8 and 9 have a slightly different approach to CORS, called XDomainRequest (XDR). If you are a jQuery developer you can easily implement XDR with CORS by leveraging a great code library from Daniel Kastner (https://github.com/dkastner/jquery.iecors). You can detect whether CORS or XDR is available by using the following code segment from the IEBlog:

// Script running on http://apps.visionsciences.com in IE10

var xhr = new XMLHttpRequest();

if ("withCredentials" in xhr) {

// CORS is supported

} else {

// Fallback behavior for browsers without CORS for XHR

}

Or, if you’re using jQuery, you can use the code shown in Figure 1.

// Script running on http://apps.visionsciences.com

if (jQuery.support.cors) {

$.ajax({

url: "http://hr.visionsciences.com/data.xml",

dataType: 'text xml',

type: 'POST',

success: function (data) {

alert("Success!");

},

error: function (ex) {

alert(ex);

});

}

else {

// Fallback behavior for browsers without CORS for XHR

}

Figure 1 Use this jQuery code to determine whether a browser supports CORS or XDR.

CORS can be used for much more than reading data. Our example focuses on getting data from another location. More complex requests can be accomplished using preflight requests. I will not dive into the details of CORS with preflight in this series, but you can find information about it on the IEBlog and in the W3C documentation.

Mashing with iframes

There is more to a mashup than Ajax requests; you can also have windows into another location via frames. From a security perspective, iframes have traditionally been a point of concern. Content inside a frame can access resources on the calling page, and historically this has been leveraged for some very nasty attacks, such as clickjacking and key-stroke redirection. How do good frames go bad?

Consider the following: in our sample application we need to include the HTML file from security.visionsciences.com/med-intel.htm. The security department updates this HTML by hand and does not have a review process prior to posting. In the past, disgruntled members of the security staff have defaced the page with comments about how the security department is overworked and understaffed. While those employees have not posted any malicious scripts yet, they could, and the act would go unnoticed. If the goal of the project is to simply display the information from that page, we could show it via iframes, but how do we mitigate the potential of malicious code being injected into our page through the frame?

Back in the days of Internet Explorer 6, Microsoft introduced an attribute to the iframe: security = restricted. Adding this attribute cast the frame’s contents as a Restricted Site (Internet Options, Security tab, Sites setting), which by default did not have scripting enabled. Any script on the page in the frame would be disabled, as well as scripts on any nested pages. HTML5 is using a similar concept with more granular control in the new sandbox attribute of the iframe element.

Using the sandbox attribute casts the frame as a unique origin (remember SOP) unless you instruct it otherwise. By default, according to the W3C draft, using sandbox disables the following actions:

  • Form submission
  • Script execution
  • Links targeting other frames or the top document
  • Plug-ins being instantiated or executing code in other frames or the top document
  • Pop-ups disabled (in the W3C standard, this is referred to as “auxiliary navigation”)
  • Rendering a nested frame “seamlessly,” meaning that it appears to be part of the page without the window frame.
  • Automatic features such as setting focus on a form or starting a media file.

To provide flexibility in implementation, the sandbox attribute can have multiple allowed settings, which keeps the control you need while reducing your potential attack surface. When code calls the sandbox attribute, all of the following actions are disabled, leaving it up to developers to allow the behaviors they want the frame to be able to perform:

  • allow-forms – Allows forms submission by the sandboxed content
  • allow-popups – Allows popups to be launched by sandboxed content
  • allow-same-origin – Allows the sandboxed context to communicate back to the calling site
  • allow-scripts – Allows scripts to execute inside the sandboxed content
  • allow-top-navigation – Allows the sandbox content to navigate to the top-level browsing content. This could be used if you want the frame to be able to control navigation for your site.

Using the sandbox attribute is very simple, but understanding the behavior of nested sandboxes requires more study. First, let’s look at how to implement a quick sandboxed iframe:

<iframe sandbox src="http://security.visionsciences.com/med-intel.htm"></iframe>

This code invokes an iframe that does not permit any of the above actions (because all are disabled by default). If you want to allow top-level navigation and popups, you would update the iframe as follows (notice that the values of the sandbox attribute are space delimited):

<iframe sandbox="allow-forms allow-popups" src="http://security.visionsciences.com/med-intel.htm"></iframe>

As common sense tells you, certain combinations of sandbox values can lead to unintended security consequences. Combining allow-scripts and allow-same-origin permits the sandboxed content to execute scripts on the calling page—scripts that can remove the sandbox attribute from the iframe and circumvent your security control. While you might see this and think to yourself, “Well, of course, I would not do that,” you must consider how nesting sandboxed content works.

Imagine that you use the iframe shown earlier to embed med-intel.htm in the sample application. One of the security staff has used an iframe on the med-intel.htm page, which provides a view to www.some-fake-news.com/news-feed.aspx with the following iframe element:

<iframe sandbox src="http://www.some-fake-news.com/news-feed.aspx"></iframe>

Based on these items, according to the W3C sandbox proposal, would the news-feed.aspx page support pop-ups? If you answered no, you are correct. What is allowed in the sandbox is determined by the

most restrictive settings. In our example, we state in the main frame (security.visionsciences.com) that forms and popups are allowed. In the next frame, we declare only the usage of the sandbox and do not permit anything. The second frame does not permit pop-ups, so the sandbox will disable them for some-fake-news.com. Your trust in the framed content and the functionality that your users need, dictate how restrictive you make your sandbox. Remember that any restrictions you place on the root carry through the nested frames. If you allow a behavior on the root, it must be allowed in subsequent nested frames to function in those frames.

The inheritance behavior described here is based on the W3C draft. In practice, browsers could implement it differently. Always check your sandbox inheritance to be sure that you are aware of your security exposure. For more details on W3C’s sandbox draft, check out the “Sandboxing section.” This section provides all the details necessary to understand the inputs and outputs of how browsers are to interpret the sandbox attribute. From there, research your favorite browsers (or the ones your users use) to determine how they implement sandboxing. Unfortunately, the sandbox attribute is just now becoming available to browsers. Newer versions of Internet Explorer (version 10) and Firefox (version 13) support it, while both Chrome and Safari have supported sandbox for a few versions now. You can explore the implementation in Internet Explorer 10 at ttp://ie.microsoft.com/testdrive/HTML5/sandbox/Default.html.

Note that sandboxing is not supported in all browsers. Check whether your users’ browsers support sandboxing by using the following JavaScript:

if ("sandbox" in document.createElement("iframe")) {

//sandbox is supported

}

else {

//sandbox is not supported

}

Use the sandbox attribute as a single piece of your defense-in-depth approach because not all browsers support it. In the third article in this series, I’ll examine how to add layers to your defense using the “constrain, reject and sanitize” approach to further secure your iframe content.

Next Time: Who Can You Trust?

This article started by examining the basics of consuming data from external sources. You learned how cross-origin resource sharing (CORS) allows applications to consume data from other domains and break free of the same origin policy (SOP). We also examined the most basic mashup technique of using

iframes to pull content into an application. CORS allows data into applications, while sandboxing provides a layer to a defense-in-depth strategy. In the next article, I’ll look at how a risk-based analysis of data sources can drive your sanitization activities, and then we’ll move on to implement the input validation process of constrain, reject and sanitize.

About the Author

For the past ten years Tim has been building web applications using JavaScript, ASP.NET and C#. Now Tim leads the development team at FrontierMEDEX building online medical and security intelligence tools. Tim is a CISSP and CEH specializing in secure software development. Find Tim on: Tim’s Blog Twitter: @seccode.

0 Comments
Supported By

Deals

Web Browsers Icon Set
Food Icon Set
Flat Icon Set

Flat Icon Set

100 icons