When a Windows Store app written in JavaScript is installed on a machine, its source code is basically sitting there, ready to be loaded into the apphost process at runtime. This does cause some developer angst, as that same source code is basically sitting there, also ready to be examined by an enterprising user with admin privileges. For this reason, JavaScript developers start thinking about minification or obfuscation to make it at least harder (I won't ever say impossible) for others to borrow or outright pirate their code. It's also important in the gaming sector to prevent cheating (whether real or perceived). In this post, then, I wanted to note a few things you can do to protect your app.

First, check out the post on the Windows 8 Developer Blog called Designing a simple and secure app package – APPX. Most of the article is about protecting the consumer through digital signing and so forth, the but near the end it talks a little about deployed app security. In the former case, the digital signature of a package applies to its entire contents, thereby giving the system the ability to detect whether the package–your source code that's just sitting there on the file system–has been tampered with. Thus if a, shall we say, creative user decides to hack a game to improve their high scores,* the system will prevent that app from running at all.

Next, to protect the source code itself, you can certainly use whatever minification/obfuscation techniques you already know for JavaScript. This makes it harder for someone to read your source code, though reverse-minification tools do exist.

On the subject of minification, note that the reduced size of JS/CSS/HTML files is really quite unimportant for apps. For one, JavaScript is automatically converted to byte code on installation as a startup optimization. Minification could save a little memory at runtime and perhaps make your package size smaller, but this is often insignificant compared to the effect of images. Indeed, making a 3-5% change in compression for PNGs and JPEGs will probably save more space than minifying text files without a noticable impact on image quality. It's also important to choose the right image format–photographs will typically compress better in JPEG than PNG, and if you can use GIFs, those work great for line art or graphics with only a few colors and long runs of similar colors. Similarly, small adjustments of the bitrates in audio and video resources would reduce the package size much more than minification.

Back to obfuscation–at this time, further protections of JavaScript code aren't available at this time. Clearly the platform could do more here, but we'll have to wait and see.

In the meantime, what else can you do? One solution for this is to keep code on a server and acquire it at runtime. This can be intercepted with network sniffers, of course, and one can always attach a debugger to the app at runtime. The Windows Store certification requirements also specifically disallows executing code in the local context that's obtained from a remote source (section 3.9). You can do this in a web context, however, and pass the results to the local context. Similarly, you can execute code on the server and return the results. With Store requirement 3.9, though, you have to avoid about driving the app's interactions with the Windows Runtime with those results lest you violate the policy.

Beyond this, you can move critical or sensitive code–that is, algorithms you want to hide–into Windows Runtime components. These can be written in C# (which is more obfuscated but still reversible, and introduces more overhead when used with JavaScript) or C++ (the best option, as reverse-engineering optimized assembly code is a strong, but not perfect barrier). Private encoding/encyrption algorithms are a typical candidate for such components, but other important logic can benefit as well.

In the end, it all depends on the level of security you're trying to achieve, recognizing that when the code is on a client machine, there simply isn't a foolproof way to keep it safe from the most determined individual. (Even running everything on a server isn't 100% secure, as hacker groups repeatedly demonstrate.) So it's a matter, really, of erecting roadblocks along the way that will deter different levels of threat.

If you've found other methods that work too, I'd love to hear about them in the comments.

 

 

*If you remember the Space Cadet pinball game that first came out with Windows 95, I eventually tired of playing through all the missions and levels. With a little exploration of its massive .dat file, I reverse engineered the data structures that determined how many lights and points you got for each mission. By bumping those up (dramatically) using Visual Studio's hex editor, it was much easier to advance enough to play the more advanced missions. In my case I just wanted to enjoy the game without the frustrations of slogging through all the earlier missions each time, but of course my scores looked pretty good too!


  • http://gravatar.com/pkursawe philk

    I understand the reason behind 3.9 yet I would like to download “GreaseMonkey” style snippets with user permission into the app and run them in the local context.

    How is the Store team going to find out that code from a remote source is loaded into the local context anyway? Do they actually read the sourcecode? The WACK tool does not detect the code that loads remote scripts.

    And its pretty easy to do:
    WinJS.xhr(“https://greasemonkeyscriptsformyapp/scrip1.js”).then(function(response) {
    try {
    new function(response.responseText)();
    } catch (e) {
    }
    });

    That’s great for fixing the app without having users to wait for cert in the store, to fix certain data for specific users or write “plugins” for apps.

    I think the Store policy should allow publisher/MS signed, remote scripts to be executed in the local context with user permission.

    Such script would have to be digitally signed by the app publisher like this:
    —–BEGIN SIGNED SCRIPT—–
    Hash: SHA256

    your script
    —–BEGIN SIGNATURE—–
    Version: 1.0

    O69SDar2lCdDAB4Vcyes8PppDU+h8K5rKozSkIhKqmPDXtmCtcCiW77TRzsid3La6ELjj45odw3V7RcJzWpqrZLYsf25lczws8JldLyBjBC7vZZPTBuyqxipCTbvp6ERU5SceJUu/7BPpuFjblufzgfY24keDhVlgRIUq3gOeOzmTY6Ug1n765U77/5OJNYgMIwwPu5Rk9zDqyZKrCdFOkn7Z0QZ+AvvkR+6lDzonOo6/HFPb6W536CrBP1tAZYSLgoBzuRO7t1zGK+Mv98q7oxU6E/dUkTydKB2Vo4sm36gFYnClSxJDL3McMUL01HLkz6V+0fW/pqYhThxqnJVI91FftbTt5Ov+vvlCBenq+GFIHy02MDrG2KZ26Zg6PTdPr8Ppar2kq+J4l634j+eHWmPVQvAlzesrr/kZLzcMevibHqfebAJLwBdxk6RNLC0KGTFASoVCQcX038dm99V40fri8l68ZpAbPhr8D+bGHmgKwLmRqH1zbFhAqS67XgS9lfwrkAZv+prElcAeiCKeaaJUid9Yypb8JM/W2TocWqJFDxxXXv+5Qu8DP33+2JiVcn6FUt7RSm5VtLIe5Nhtdn28VFscycx8O6pjFp65JVR34LyEpLqEH4dfxo1+quwoLTBFiFc10Bh9idTIrXFeZ6SQVrNt+oiMtkVR+ACMCQ=
    —–END SIGNATURE—–

    Then the WinRT/JS API allows to load such script only when the signature matches with the app publisher.

    We already have MSApp.execUnsafeLocalFunction please allow us remote scripts also (with user permission).

    I have working code for that in place and will public source it soon.

    • http://www.kraigbrockschmidt.com kraigb

      Thanks for the comment. About Store certification, that process involves more than the WACK does itself (the WACK is just the first test), and it’s not hard to trace network requests from an app to see if it’s grabbing remote script. I don’t know what the cert team does, exactly, but it is their job to enforce the requirements.

  • Julian Atanasoae

    Great article! It’s good to know that there are ways to protect your intellectual property in Windows 8 apps.

  • Pingback: Windows Store Developer Links – 2013-04-15 | Dan Rigby