Search
RSS Feed
Twitter

Entries in SendSafely (3)

Tuesday
Nov262013

Pushing CSP to Prod Slides From Appsec USA

Note: This post has been crossposted from the SendSafely blog. You can find the original post at http://blog.sendsafely.com/post/68106453098/slides-from-owasp-appsec-usa.  

In case you missed the presentation by SendSafely’s Brian Holyfield and Erik Larsson at OWASP AppSec USA, we’ve posted a copy of the deck in our GitHub repository.  Brian and Erik discussed some of the challenges we faced here at SendSafely when implementing Content Security Policy (CSP) on our site.  There will also be a video recording of the talk posted in the AppSec 2013 YouTube Channel.

Thanks again to everyone that came out to the conference and especially those that came by our booth to say hi. We hope you all had as much fun as we did!

Tuesday
Feb052013

Using Content Security Policy to Prevent Cross-Site Scripting (XSS)

Note: This post has been crossposted from the SendSafely blog. You can find the original post at http://blog.sendsafely.com/post/42277333593/using-content-security-policy-to-prevent-cross-site.  

On SendSafely we make heavy use of many new JavaScript APIs introduced with HTML5. We encrypt files, calculate checksums and upload data using pure JavaScript.  Moving logic like this down to the browser, however, makes the threat of Cross-Site Scripting (XSS) even greater than before. In order to prevent XSS vulnerabilities, our site makes liberal use of pretty aggressive client-side and server-side encoding APIs.  These APIs are based on the OWASP ESAPI library, so we have context-specific encoding methods for pretty much every scenario. Even so, we recognize that it is very difficult to rule out all possible ways to inject code, including human error on our part. For this reason we chose to also implement Content Security Policy (CSP) for SendSafely.

CSP is a new security mechanism supported by modern browsers. It aims to prevent XSS by white-listing URLs the browser can load and execute JavaScript from. The server can, by specifying specific CSP directives, prevent the browser from executing things like in-line JavaScript, eval()setTimeout() or any JavaScript that comes from an untrusted URL. The policy works as a white list, only domains listed are allowed to execute, everything else will be blocked.

The Content Security Policy in SendSafely
In SendSafely, our Javascript files are all loaded from a dedicated host that doesn’t run any dynamic content (static.sendsafely.com). The exceptions to this are for certain third-party JavaScript APIs that we load from an external domain, specifically Google Analytics and reCAPTCHA.  Text-to-JavaScript functions like eval() and setTimeout() are blocked across the board, even if the script is loaded from one of our white-listed hosts, as is any in-line JavaScript

Use of a strict CSP makes it significantly harder to inject executable JavaScript into application pages since the code must come from a trusted server.  The typical XSS attack using un-encoded output on one of our pages won’t work when the CSP is enforced.  In fact, any JavaScript embedded on our content pages (even JavaScript we put there) gets blocked by the policy.  Pretty cool stuff.  

So you may be asking yourself, does this mean XSS is nothing but a memory? Sadly, this is not the case.  For starters, CSP is still fairly new and only supported by recent versions of Firefox, Safari and Chrome. Internet Explorer 10 (IE10) supports a subset of CSP options, but the ability to white list domains is unfortunately not one of them.  Aside from limited browser support, data dynamically loaded into the page from JavaScript is still potentially vulnerable. A strict Content Security Policy should therefore not be considered the end-all solution to XSS . Think of CSP more like a safety belt, which is nice to have when your car crashes.

Dissecting our Policy
Now let’s take a look at the CSP policy we use on www.sendsafely.com and dissect it a bit.  One of the first things to note is that if you are going to implement CSP, you must realize that there are some browser compatibility nuances to deal with.   The main thing to note is that Safari uses ‘X-WebKit-CSP’ as the header name for implementing CSP, while other browsers have standardized on ‘X-Content-Security-Policy’.  Another glitch that affects Safari is that a severe bug in the CSP implementation on Version 5.1 essentially blocks authorized content when a valid CSP is specified.  As a result, you’ll want to specifically detect when Safari is used and send either the ‘X-WebKit-CSP’ header or no header at all (if Version 5.1 is used).

To keep our policy as strict as possible, we use two different policies depending on what the page needs to do.  The stricter policy is used for all pages except the ones that handle encryption and decryption (the reason for this will be discussed in a separate follow up post).  For simplicity, the more strict policy will be explained here.

X-Content-Security-Policy: default-src ‘none’; connect-src ‘self’; script-src https://static.sendsafely.com https://www.google.com https://ssl.google-analytics.com; style-src ‘self’ ‘unsafe-inline’ http: https:; img-src ‘self’ https://www.google.com https://ssl.google-analytics.com; report-uri /csp-reports;

The header is divided into different sections that are each separated by a semi-colon. The “default-src” directive defines the security policy for all types of content which are not expressly called out by more specific directives.  We opted to set the default-src value to ‘none’, meaning that by default we allow nothing to load.  If we stopped defining directives here, the site would be completely broken, so now we need to open up the policy and allow specifically what we need to load.  

Now that we’ve explicitly denied everything by default, we need to add back the specific content policy options our site needs.  On SendSafely, we have a hand full of resource categories that we need to add policy settings for.  Each of these are outlined below, along with the CSP directives for each:

  • Ajax Requests - Several pages within our site use the browser’s XMLHttpRequest (XHR) object to make HTTP requests from within our JavaScript code.  In order for us to make these requests we set the “connect-src” attribute to “self”, so scripts on our site can make XHR requests back the server but nowhere else. This attribute is another place where we run into compatibility issues across different browsers.  Specifically, FireFox decided to name this directive “xhr-src” instead of “connect-src”.  To account for this, our CSP code does some basic browser detection and if we detect that FireFox is being used, we change the directive name accordingly.  

  • JavaScript - As mentioned previously, we load all of our internal static JavaScript from a dedicated host (static.sendsafely.com). Additionally, we’ve chosen to load the Google Analytics and ReCaptcha JavaScript files from their origin domains on google.com.  Unfortunately the ability to allow just a sub-path of a host (like /scripts/) is not supported. Since ReCaptcha script files get loaded directly off of the main www.google.com site, our “script-src” directive includes https://static.sendsafely.com, https://www.google.com and https://ssl.google-analytics.com

    Having such a large site like www.google.com in our CSP whitelist is understandably something we are not thrilled about.  The ability to allow sub-paths of a host is slated to be introduced in CSP 1.1, but until then we’ll have to live with it.  The good news is that Google takes security very seriously, and they take great care to avoid script injection bugs on their website.
  • CSS - Our site design makes heavy use of in-line CSS for styling various UI attributes.  As such, the style-src directive includes a value of “self” (that allows us to load CSS files from the same host) and a value of “unsafe-inline”, meaning that we can use in-line CSS from within our HTML pages.  We recognize that by allowing in-line CSS within our pages, there is a minimal increased security risk since someone could potentially be mischievous if they found a way to inject markup into one of our pages.  Given the cost/benefit of refactoring the UI to completely avoid any in-line CSS, however, we decided this is a tolerable risk that we can live with for now.  

  • Images - Our img-src directive specifies both “self” and the two previously mentioned google hosts (https://www.google.com and https://ssl.google-analytics.com)  as the authorized origin hosts for all image content  For the most part, our site only loads images from the same host.  The exception to this is reCaptcha, however, since reCaptcha loads various images from www.google.com domain.  

  • The final part of our CSP header is the ‘report-uri’ directive.  This directive tells the browser to send us a report of pages that violate the Content Security Policy. The  violation reports consist of JSON documents sent via an HTTP POST request to the specified URI.  Using this option, we can monitor for events that trigger CSP exceptions and quickly take action if we think there may be a problem with our site.  The reports are also great to use during testing and development in order to debug CSP issues you might encounter.

Final Notes
A few final notes: CSP is a great tool to add an additional layer of protection against Cross-Site Scripting. If you’re building a new application, CSP should be considered as a solid defense in depth security control in the never-ending battle against cross-site scripting. Writing client-side code which is designed to use CSP will save precious developer cycles in the future, if code must be migrated to work with CSP.

Implementing CSP on our site proved to be a very interesting exercise.  We’ll provide more details on some other aspects of our Content Security Policy implementation in a follow up post here on our blog. 

Wednesday
Dec192012

Introducing SendSafely.com: An Easier way to Securely Send Files

 

Imagine this scenario:  It is 4PM on a Thursday afternoon.  You’ve worked hard all week, doing what just may be your best work ever.  You’ve been scrambling to finish up a report you owe your favorite, but most demanding client.  You promised to deliver it to them by the end of day, since their boss needs the report before the go/no-go meeting in the morning.  

It’s been peer reviewed, and you give it your final once over to make sure everything is perfect.  You open your email client, attach the report to the message, and then press the GPG  “Encrypt” button.  The mail client chokes a few times, which you chalk up as normal when dealing with GPG, and finally the email is sent.  Life is good.  

As you reach into the beer fridge to crack open a celebratory stout in the mini fridge you keep below your desk (doesn’t everyone have one of those?), you see a reply come into your inbox.  “Thanks for the report.  I had to duck out of the office early today to make it to my son’s baseball game.  Please send the report to my assistant instead so he can have it ready for tomorrow’s meeting. You’re the best!”.   

Hmm, ok no problem…let’s just send the report to the assistant instead.  Obviously, sending the plain-text file via email is not an option.  You send the assistant an email asking for their GPG/PGP key.  “What’s GPG?” the assistant replies.   Ok, not surprising.  Time to move to Plan B…send them an encrypted ZIP file.  You start by generating a nice random combination of letters, numbers and symbols.  You use that as the password to encrypt the ZIP with AES-256, and send it off.  Now all you need to do is call them with the password.   

As you pick up the phone to call them, a reply comes into your inbox from [email protected] “Error 582 - Email Attachment Security Policy Violation”.  You curse to yourself as you vaguely remember suggesting to them a few months back that they bolster their email filtering capabilities by using a cloud service like Google’s Postini, rather than the traditional signature-based software they were previously using.  Unfortunately to your disadvantage, this message confirms that they took your advice.  In an act of desperation you rename the “report.zip” file to “report._”, hoping that the mail filter is dumb enough to just look at the file extension.  The identical auto-reply that comes back moments later, confirming what you already knew…it wouldn’t be that easy.

Ok, time to move to Plan C, sending the file through a web-based server your company runs specifically for such situations.   You remember the company network admin boasting about the steps he took to harden the server when it was first stood up, but you decide to stick with the encrypted ZIP as an extra layer of protection.   You upload the file, publish it to an external link, email the link to the assistant, and call them to provide the password.  “Ok, the file looks like its downloading…hold on and I’ll make sure I can open it.”.  You start to breathe a sigh of relief as it looks like you are finally close to being done.  

“I’m opening it now.”, says the assistant as you slowly reach down once again towards the mini fridge.  “Hmm, it’s telling me Windows cannot complete the extraction.”  You quickly realize you’ve been foiled once again, when you remember that Windows can’t natively open AES-encrypted ZIP files (Windows can only open ZipCrypto protected files natively).  As a last ditch effort, you ask the assistant to Google the terms “WinZip” or “7Zip” and follow the download links for each, but the WebSense proxy they recently implemented (also based partly on your advice) quickly blocks both downloads.   As you start to pull out your hair and think of what to do next, you wish there was a better way.  Well now there is.  

Meet SendSafely
Some of you may know we recently previewed a new platform, which we developed, at OWASP AppSec USA in Austin, TX.  The platform is called SendSafely, and it’s designed to facilitate secure file exchange using only a web browser.  Being a team of security consultants, we were repeatedly faced with multiple variations of the scenario outlined above.  With SendSafely, you only need a modern web browser to quickly and easily exchange encrypted files with anyone.  No pre-shared keys, no software to install.  If you’re interested to see how it works we’ve got a high-level explanation here and a more detailed explanation here.  If you haven’t tried it out, we encourage you to sign up for free and take it for a test drive. 

Our goal with SendSafely is to become the standard for secure file transfers.  We aren’t a Dropbox replacement, nor do we aim to be.  Think of them as the mini-storage unit you rent every month to hold onto all of that extra stuff you own.  Instead, think of us as the secure FedEx or UPS of the digital world.  If you want to send something important to someone else, and you want to get it there fast and securely, then use SendSafely.   

You can also check out the SendSafely Blog, where we’ll be blogging about the challenges we’ve dealt with, and things we’ve learned, while building a secure cloud-based application platform.  Stay tuned for more updates, and tell us what you think of SendSafely…we’re all ears! You can reach us at [email protected] or feel free to post your comments right here on our blog.