Jaap Vossers' SharePoint Blog

Just another WordPress.com site

Archive for the ‘Security’ Category

Malicious Sandbox Solutions in SharePoint 2010 – my private data has been stolen!

with 4 comments

We all know about the existence of Sandbox Solutions in SharePoint 2010 and why you would want to use it. We also know that server side code running in the Sandbox is very restricted. Things like accessing the server’s file system, using the SPSite constructor, sending e-mails, making web requests, plus loads of other actions cannot be performed when running in the Sandbox for the sake of security.

It is easy to start thinking that Sandbox Solutions cannot do too much harm and that any damage done stays within the walls of the Site Collection. The aim of this blog post is to bust this myth and make people aware that they are still responsible for validating the contents of any Sandbox Solution they activate on their Site Collection.

What if I told you I have developed a Sandbox Solution that upon activation collects documents and list data from your site collection and sends it to me, the evil developer, outside your Site Collection walls? Would you be surprised to hear this is possible? I think many people would be.

It is possible.

  1. Evil Dev produces Malicious Sandbox Solution
  2. Site Collection Admin uploads and installs Malicious Sandbox Solution
  3. Malicious Sandbox Solution collects private data from Site Collection and sends its to Evil Dev


Now it’s time to see it in action.

For obvious reasons I will not post the full source code, but I am happy to explain how it works.

I am assuming all of the code runs under the context of a Site Collection Administrator.

Note that the following “solution” does NOT depend on the fact that it runs in a Sandbox. In fact, as Jan Tielens has kindly pointed out, the same result could be achieved with a JavaScript only solution.

Step 1 – Save site as a template through JavaScript in the background
Let’s leverage the “Save as Template” functionality as used in /_layouts/savetmpl.aspx to produce a WSP that contains the site with all its contents, including documents in document libraries and lists with data. The first hurdle we need to get past is to figure out how we are actually going to achieve this, since SPSolutionExporter.ExportWebToGallery() is not available in Sandbox Solutions. One way to hack around this is to use jQuery to perform an AJAX POST to /_layouts/savetmpl.aspx providing all the POST parameters that it expects. Remember, HTTP is stateless. We need to perform an initial AJAX GET to /_layouts/savetmpl.aspx to obtain the values of __REQUESTDIGEST, __VIEWSTATE and__EVENTVALIDATION so we can trick ASP.NET into thinking that the POST we are about to perform originates from a user looking at /_layouts/savetmpl.aspx in his browser. All the other post parameters that the page expects to receive as part of a POST can be obtained using Fiddler as we perform a manual form submit through the browser on /_layouts/savetmpl.aspx
All of our JavaScript code will run on a custom Web Part page that is loaded inside an iframe, except for the bit of JavaScript that is responsible for creating this iframe. This Web Part page plus the custom Web Part that lives on this page have been deployed to our Site Collection using Features that reside in our malicious Sandbox Solution. A Feature containing a CustomAction with Location=”ScriptLink” takes care of loading our JavaScript file on every page.
Once we have the JavaScript in place to initiate the creation of the template, we need to wait for the process to complete. Lucky for us, the /_layouts/savetmpl.aspx page blocks until it has finished producing the template, so we know that when the callback of our AJAX POST is called we are ready to rock. In the next step I will explain why it’s important for the script to be informed when the page has finished creating the template.

Step 2 – Get access to saved template data in JavaScript code
We have successfully managed to save the template in the Solution Gallery of the Site Collection. Now we need to access this file. I mean really access the file contents in JavaScript code. Unfortunately we can’t pass around binary data in JavaScript, so we need an alternative. Wouldn’t it be cool if we had access to a JavaScript string variable containing a base64 encoded string that represents the binary data of our freshly baked template? Yes, that would be very cool. The Web Part that lives on the Web Part page can do this for us. As part of the page lifecycle, the Web Part looks to see if the expected template file exists in the Solution Gallery (the Solution gallery is just an SPList and the template file we are looking for is just an SPFile). If the file exists, it gets the binary data of it, converts it to a base64 encoded string and renders a snippet of JavaScript that defines the string variable we are going to use in step 3. The first time the Web Part page was loaded inside the iframe the template did not exist in the Solution gallery, hence it did not render this JavaScript variable, which was also a hint to our JavaScript to initiate the creation of the template. Remember we said we have a callback in our script to notify us when /_layouts/savetmpl.aspx has completed producing our template? Excellent – because inside our callback we are going to force our iframe to refresh, causing the Web Part to output the base64 encoded string variable.

Step 3 – Send template data to a remote server
Now what we have our data available in JavaScript, how do we “send” this to the outside world? Perfoming AJAX calls to anything that is not on the same domain will be noticed or even blocked by the browser, so this is not an option. This is not true for regular form posts. All we need to do is create an html form, set its action attribute to point to a “collector page” somewhere on the internet. This page can then listen for incoming form posts and transform the posted base64 encoded string back to its binary representation and save it somewhere as an actual file. Your data has just been stolen…

To conclude
I don’t think there is anything technically wrong with the security model of Sandbox Solutions. The point I am trying to make with this blog post is that even though there is a lot of stuff that cannot be done from within a Sandbox Solution, there is still quite a lot of stuff that can be done -which can be seen as good or bad!

Do not blindly trust a Sandbox Solution. As Site Collection Administrators, we are still responsible when it comes to assessing and validating the trustworthiness of a Sandbox Solution and its source.

What about custom Solution Validators? You could use these to only allow certain pre-approved or signed Sandbox Solutions to be activated for example, but it comes at a price. You compromise on business agility in order to increase security. Kind of reminds me of Farm Solutions…

Written by jvossers

November 12, 2010 at 9:34 am