Wednesday, January 20, 2010

The Acrobat JavaScript Blocklist Framework

Adobe recently announced and released the Adobe Reader and Acrobat JavaScript Blocklist Framework. I've had a little bit of time to play with it and would just like to share my thoughts. First of all, I am very pleased with this new blocklisting feature. Until now, when we knew about 0-day being actively exploited in the wild using JavaScript in some manner, we would just turn off JavaScript in Adobe products (Reader, Acrobat, etc...) all together. Personally, I could live without having JavaScript in my documents, but that's a totally different discussion. I understand why some people might want that feature for their PDF documents and why for them at least, turning JavaScript completely off would not be an option. So let's say, for example, that you are running Adobe Reader 9.2.0 which is vulnerable to the DocMedia.newPlayer JavaScript API bug. You decide that it is in your best interest not to allow that method from ever executing. How would you go about blocking that? The official document put out by Adobe says: the "JavaScript Blocklist can be in two locations" on a 32-bit Windows system:
- HKLM\SOFTWARE\Adobe\<product>\<version>\JavaScriptPerms\tBlackListand- HKLM\SOFTWARE\Policies\Adobe\<product>\<version>\FeatureLockDown\cJavaScriptPerms\tBlackList
The first key is "modified by Acrobat and Adobe Reader patches whenever an API is deemed vulnerable" (this feature is currently in testing with a select group of beta testers). I decided to modify the second registry key. The manual configuration of this registry key was tricky did not exist on my system with Adobe 9.2.0 installed. Thankfully it's not hard to create a registry key, and I did just that. Note that everything you type is case-sensitive when it comes to the registry keys related to the blocklist, from the value name to the values themselves. I spent a ridiculous amount of time trying to figure out why the blocklist wasn't working. It was because I had manually created a key called tBlacklist instead of tBlackList. Now came the time to test the effectiveness of the blocklist. I entered the Javascript API function docmedia.newplayer in the registry as indicated in the document by Adobe. I typed in:
How to verify if I had typed it in correctly? There was obviously no confirmation that I had blocklisted docmedia.newplayer. I went through the options of Adobe Reader and nowhere was there a mention that docmedia.newplayer was blocklisted. What was I going to do to next? Wait until I received a PDF that had code to exploit the vulnerability to see if the blocklist worked as it was supposed to? I decided to create a simple, harmless PDF that invoked that function to see if the API call would get blocked. I could successfully open the file without the function being blocked. This time, I quickly pinpointed the reason for that: API functions are case-sensitive and entering docmedia.newplayer is not the same as entering DocMedia.newPlayer. My concern was then that obfuscation techniques in Javascript could fool and circumvent the blocklist blocking. I tried basic evasions techniques:
  • obfuscation function names, function contents
  • lexical transformation
  • control transformation
  • data transformation (data structure)
There was no fooling Adobe Reader into executing the blocked function. It seems like Adobe Reader is hooking the function calls and is not going through the code trying to perform a string match. As of today, there isn't an official list of Adobe Javascript API functions to block, but I'd suggest adding the following to your blocklist just because these functions have been heavily exploited in the past several months: Util.printf (CVE-2008-2992) Collab.getIcon (CVE-2009-0927) Spell.customDictionaryOpen (CVE-2009-1493) Doc.syncAnnotScan (CVE-2009-2990) Doc.getAnnots (CVE-2009-1492) DocMedia.newPlayer (CVE-2009-4324) Very often, malware will escape Javascript code in order to avoid detection. The code is unescaped and evaluated at runtime. Therefore, these two function are commonly seen in malware and usually used one right after the other:
Unfortunately, these functions cannot be blocklisted through the Acrobat Javascript Blocklist Framework. Maybe it's just because they aren't, per se, Adobe Javascript API functions? We would love to be able to do that in the future, though. I also wanted to blocklist these two function because they have been exploited in the past:
app.CheckForUpdate (CVE-2008-2042)Collab.collectEmailInfo (CVE-2007-5659)
Turns out these are unpublicized Adobe Javascript functions and perhaps because of their nature, cannot be blocklisted. Finally, here's the blocklist that I propose, should you want to use it:
And here are simple harmless PDF files to test the implementation of your blocklist. Upon the functions being successfully blocked, you will see a yellow bar displaying "A JavaScript that this document uses is disabled for security reasons".


  1. I've a video of the framework in action here:

    And I've been trying to redefine unescape via Folder Level JavaScript, but this doesn't work because of the different context.

    If I find no other way, I'll do it with a patch in memory.

  2. Definitely a step in the right direction.

    @DidierStevens: In memory patching is a great approach but eventually all JavaScript engines need a simple mechanism to blacklist the seemingly-only-used-by-malware API calls like eval() and unescape().

  3. Great post!

    The two API's you mention not successfully blacklisting, no longer exist in the 9.x release. So, rather than hit the blacklist, attempting to call those 2 functions simply errors out for lack of any such function. It looks from your article like you were testing with 9.x.

    app.CheckForUpdate does not exist past version 7. Since version 7 does not have the blacklist feature, there's no platform where you can experiment with blocking that. :-)

    Collab.collectEmailInfo OTOH you should be able to see the Blacklist working in the current release of 8.x. (Assuming of course you replicate your blacklist registry key at the appropriate path for where v8 will look.)

    Thanks for giving the Blacklist stuff a hard look, and, for helping get the word out about it. We appreciate it!

    (Jim Hebert, Adobe Secure Software Engineering)

    PS One last note, about the 2 different places you can put things on the blacklist -- to me it comes down to what strategy you want to employ.

    * If you just want to blacklist certain API's while there's an unfixed vulnerability floating around, but, you'd like the Updater to take care of un-blacklisting them for you at the time of installing the fix for that API, the location that the installer touches is the right choice. (As it says on -- "APIs are also removed from the blacklist whenever a fix for a vulnerability is provided by the current patch.")

    If this is a person's strategy, then they would also probably not be as interested in permanently blacklisting the API's proposed at the bottom of the blog post, since fixes are out for all of those.

    * If on the other hand you take a deeper theory of, if there was 1 vuln in this API, there could always be more, and, it's useless attack surface in my environment, so, let's permanently disable it, then the other registry location makes sense. And, the list proposed at the end of the blog post would make sense for people approaching it in that way.

    Thanks again!


Post a Comment

Note: Only a member of this blog may post a comment.