Martin Suchan – BloQ Random #WPdev stuff

6Jun/130

Windows 8 Share Task out-of-sandbox vulnerability

When I was recently developing one Windows 8 app that supports the "Share Contract", I've experienced strange problems when the sharing suddenly stopped working not just in my app, but for all apps launched from my account. I had to log-off and log- in to make it work again. I thought it was just some kind of temporary issue until I discovered that it cause my app. After hour of testing I've pinpointed the actual issue and came to conclusion:

Any Windows 8 app running in sandbox can break the Share Contract for ALL other Windows 8 apps running under the same account, until the user logs off and on again!

Here's the detailed explanation how to do it, it's quite simple, nothing tricky.

Quick introduction to the Sharing on Windows 8 - if you want to share any data to "Share Enabled apps" like Facebook, Twitter, SkyDrive etc, you need to get the instance of DataTransferManager and attach to the event DataRequested like this:

DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += OnDataRequested;
 
...
 
private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
}

In the OnDataRequested method you can then fill various fields like Title, Description, Bitmap, Uri, etc. The Share Target app then takes these provided data and, well, shares it. In case of Twitter it creates new tweet containing the Title and Description, optionally the link too. In case of some kind of image processing app it takes the provided image and applies filters on it, etc.

When you are providing data for the DataRequest, you might need to execute some kind of asynchronous code like loading an image from StorageFile. In this case you need to get so called DataRequestDeferral object - class informing the system, that you've not finished the data when the execution leaves the OnDataRequested event handler. The system will then wait until you call the method deferral.Complete().

DataRequestDeferral deferral = e.Request.GetDeferral();
 
// your code
 
deferral.Complete();

And here comes the root of the issue - if you forget to call the deferral.Complete() method, or maybe if your OnDataRequested method throws an exception before calling it, you will break the Internet the Share contract! Yes, that's all. Once you have forgotten to call the Complete() method, even if you close the app, or uninstall it completely, you'll be unable to share any data from any other app until you log out and in again.

Let's try it. I've created some time ago quite popular Windows 8 app "Astronomy Picture of the Day", it shows the image feed from web http://apod.nasa.gov/apod/, it can even show current picture on lockscreen or share images using the Share Task.

If you want to share an image, this is how it looks - you simple visit image detail and click the Share button, then the list of available Share Target apps appear, you can select one, for instance the Twitter and share the image:

share_ok

share_twitter

Now if I close this app and run my sample app that is not calling the deferral.Complete(), it looks like this:

breakshare

Note the progress ring and the message saying: Getting information from appxy - the system is waiting for app to provide its sharing data, but this waiting never ends.

Now if I go back to my app APOD and I try to share the image again, IT'S NOT WORKING! Somehow the other app broke the sharing. If you omit to call the deferral.Complete(), then the Windows 8 agent for sharing between apps is waiting indefinitely for this call and you cannot share from any other appa until you log-out and log-in again. This is surely a vulnerability - no app should be able to disable core system service for other apps!

apod_broken

 

Description about this vulnerability, how to reproduce it:

When the Win8BreakShareContract app is started, and the Share button in Charms bar is pressed, the app calls e.Request.GetDeferral(); but not deferral.Complete(); which makes all other Windows 8 apps not capable of Sharing using the Share contract, until the current user logs out and in again.

Note, the user even does not need to click on anything - the Share contract can be launched programatically using:

DataTransferManager.ShowShareUI();

Successfully tested on 3 different PCs, with latest patched Windows 8, x64 and x86 version as well.

No extraordinary code or method use, just plain Windows 8 app and Windows Runtime API.

 

Here's a link to the sample, please test it and let me know, if you can reproduce this issue as well. Don't worry, there is no dangerous code in it, you can check all included files and compile it by yourself.

If any of my readers got already the preview version of Windows 8.1, please test is as well if it's fixed already or not, thanks!