Wednesday, April 22, 2009

Raising the Bar? Flash Encryption, Obfuscation

[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:

  1. Developer writes some [potentially bad] ActionScript code
  2. Developer "obfuscates | encrypts" the code
  3. User hits page, downloads embedded "blob"
  4. User starts to execute Flash! file
  5. Decryption|De-obfuscation routine runs, produces valid (unprotected) Flash!
  6. 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.

"PRODUCT X uses Advanced Obfuscation Techniques along side proven Encryption Technology to provide security and protection for your Adobe Flash® SWF Files. Put simply, PRODUCT X prevents other people from decompiling or reverse engineering your SWF movie and stealing the ActionScript Code." How can a vendor make a statement like that, consciously, knowing full-well that this is just like the obfuscation techniques that are being used on JavaScript right now... their effectiveness is only marginal to the determined attacker.  You have to continue to put these types of technologies into context because if you're looking at "encrypted content" you'd think that it's secured, much like an "encrypted database" is secured from someone who steals it... until you realize the main difference is that generally the decryption routine is not included with the database but as a separate process.  This is the main difference.  Since Flash! player has no internal mechanism to decrypt|de-obfuscateflash files the work falls to the application itself, meaning it has to be included into the code blob.

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...

  1. Never put sensitive information on a client (passwords, 'hidden" URLs, validation routines, encryption routines, etc)
  2. Understand that anything on a client can be compromised because you no longer have control
  3. 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.


Ammar Mardawi said...

While your post is great and very informative on many sides, it is misleading in two important points.

First, an obfuscator's main objective is to protect the intellectual property within the code. It prevents decompilers from generating anything useful at all and makes revese-engineering requires longer time so becomes not feasible. Security through obscurity is a secondary objective. As bad as many may argue this option can be, it is still cheap to implement and does not heart.

The second thing, there is no such thing as de-obfuscation. Obfuscation is (at least should be) irreversible. The Flash Player will run the obfuscated code directly and does not require a deobfuscation step. For example, when an obfuscator renames identifiers in the code to meaningless names, the Flash Player will not mind that.

Again, I think your post is great and very informative.

Rafal Los said...

@Ammar -

First, thanks a bunch for reading and taking the time to comment. You're completely correct, and I did fail to point out that the obfuscator's main role is often to simply protect IP (intellectual property) inside the file - which is accomplished quite well.

What I should have emphasized more closely is that this post was a response to a security question... "Does an obfuscator/encryptor make my (poor) code more secure?" Of course the answer is no.

Again, thanks for pointing those 2 issues out!