[Cross-post from "Following the White Rabbit"]
On the heels of my OWASP talk regarding decompiling and analyzing Flash [see SWFScan link] files lots of you have asked "So what about Flash file encryption or obfuscation? Does that make my code any more secure?" I've done the research and talked to experts (including our very own Billy Hoffman) - and have a blog post just for those of you starving for this information.
There are a lot of Flash file obfuscators/encryptors out there... all of them hoping to raise the bar for attackers against your client-side Flash code. I'd like to make sure I properly set the background for you here - everything you'll read about is happening on the client side within the user's browser framework, meaning, it's running in potentially hostile territory.
Now let's move on and take a look at some of the ideas we're addressing. First when-ever you're discussing client-run code you have to understand that whether it's encryption, obfuscation, or magic you have one major problem: the client has to know how to un-do the magic. When the Flash! file comes to your client it has to be interpreted by the Flash! player, right? In order for it to do that it has to be readableand understandable by the Flash! player. Think about that. If the code is sent encrypted, say using some strong AES-256 encryption technology, then the player is unable to render it thus creating a quite secure, but completely unusable "blob". In order for the code to be worth anything to the client it has to be de-crypted (or obfuscated). For that to happen you have to have the routine to decrypt | de-obfuscatethe blob located within that blob, likely as a pre-cursor to the whole piece of code. You should already see a huge gaping hole here. Here's what this all looks like in terms of process from developer's workstation to client player:
- Developer writes some [potentially bad] ActionScript code
- Developer "obfuscates | encrypts" the code
- User hits page, downloads embedded "blob"
- User starts to execute Flash! file
- Decryption|De-obfuscation routine runs, produces valid (unprotected) Flash!
- Flash! player executes code, movie runs
Immediately, in the above step-by-step you'll notice that step 5 the decryption|de-obfuscation routine has to run on the client to unprotect the SWF file. This essentially breaks down to mean that the deobfuscation|decryption code has to exist on the client, within the protected SWF file. Ask yourself what sort of security that buys you, if you're including the unprotect routine with the protected code.
After wading through many different SWF encryption|obfuscation tools I've come to realize that they're selling to folks who simply don't understand the full scope of the problem. Here is an interesting quote from one vendor's marketing material. I'm not identifying the vendor... mostly to protect them from the questions you would have about their effectiveness.
The verdict? If you're depending on a code obfuscation|encryption tool to protect your Flash! files, you should probably re-think your strategy. First ask yourself why you're hoping to hide the client-side code. Intent here is key... because while the tools you're using may temporarily deter a simple Flash decompiler, in the long-run it will not protect your code. As Billy Hoffman notes "Client-code obfuscation|encryption is much like WAF (Web Application Firewall) technology, it's a temporary fix meant to increase the "time to hack" while not providing anything permanent." Including sensitive information on a client-side code blob is never a good idea. This should be self-evident but apparently there is a significant market for Flash! obfuscation|encryption tools so maybe I'm wrong. Here are a few pointers for those of you thinking about writing sensitive client-side Flash! apps...
- Never put sensitive information on a client (passwords, 'hidden" URLs, validation routines, encryption routines, etc)
- Understand that anything on a client can be compromised because you no longer have control
- Any encryption|obfuscation of client-side code has to be un-done in order for the framework to process it... thus only providing marginal security improvement
When all is said and done, to quote Billy Hoffman "It's like boxing a 7 year-old... you're going to win it's just a matter of how hard do you want to try". --Thanks to Billy Hoffman of HP's Web Security Research Group for his contribution to this blog, and his ongoing effort to protect developers from their own worst enemy... themselves.