Saturday, January 26th, 2008

Is using a JS packer a security threat?

<p>According to research done by SecureWorks we are facing a Packer 2.0 threat where hackers could use JavaScript packing mechanisms to get access to servers:

Computer hackers have taken advantage of the acceptance of these packers as suboptimal network optimization tactics and are using them as a way to evade and bypass security controls on the gateway and at the host. Consequently, exploits or other malicious code is delivered successfully because of the packer’s ability to bypass anti-virus and IDS/IPS and directly to a user’s vulnerable system.

Much of the debate around the use of JavaScript packers is analogous to the debate around the use of Windows PE executable (EXE file) packers used by malware distributors. While lessons can be found there, the information below focuses on the use of JavaScript packers specifically.

While I am personally a bit confused by the lack of examples and detail information about the exploit procedure the main crux of the matter seems to be that a lot of packers use eval() and we know for a long time that eval is evil.

The article then goes over the different packers in use and lists their problems:

  • The inability to easily verify and audit code
  • The administrative overhead of repacking code for each change
  • Suboptimal compression
  • The increased risk of false negatives which may lead to a site being used to spread malicious code
  • The increased risk of false positives, which may lead to a site or some of its functions being blocked by security controls
  • Noticeable negative impact on client-side performance.

It ends with a list of recommendations what to do instead of relying on packers on the final product:

  • Not compressing JavaScript code at all
  • Reliance on increases in average available bandwidth
  • Reliance on local and network caching
  • Not using more JavaScript functions than necessary (smaller library “builds”)
  • Using only safe whitespace/comment reduction techniques
  • Automatic application of safe techniques as a last step in the publishing process
  • The use of mod_deflate/mod_gzip for compressing the HTTP response data
  • The use of jar files to package JavaScript (these can be cryptographically signed to further enhance authenticity of code, and hence improve security)

I’ve yet to see the last option in the wild but agree with gzipping and application of compressing in the publishing process rather than using it in the final product. Personally I don’t quite think that relying on increase of average available bandwidth is a safe option though.

What do you do, or – even more interesting – have you encountered security problems by using packers?

Full article: SecureWorks – The Packer 2.0 threat

Related Content:

22 Comments »

Comments feed TrackBack URI

Now *that* is a roundabout way of saying that obfuscated code may be malicious. Which means you block it, and, well, that’s it?

Except that Dean Edward’s Packer has gotten a bit popular, so some tools don’t block it, so bad guys use Packer’s signature to fool the security tools.

Leading, very roundabout-edly, to the point: don’t make your code look as if it’s got something malicious to hide.

Comment by MarkWubben — January 26, 2008

The SecureWorks guys emailed me about this and are prepared to adjust their algorithms to allow packed code. I just have to tell them how to identify safe scripts. Mmm. How do I do that then?

BTW. Good to see that the new editors also read my del.icio.us links. ;-)

Comment by deanedwards — January 26, 2008

So we should stop packing our javascript code because some security folks aren’t skilled enough to unpack it? Sounds like the beginning of PE packers when AV companies started detecting the generic UPX headers as malware instead of unpacking. Luckily they (most of them at least) moved past that, hopefully these web security guys will do the same thing.

Even if they could convince us to stop using packers, they are never going to convince the malware authors to stop so its a moot point.

Comment by cowsonfire — January 26, 2008

We’ve been looking at the mod_deflate option rather than Javascript packers as well. Our Milescript demo application on our website (http://milescript.org) condenses automatically at the end of the publishing process using safe technqiues (reduces size of variable and method names and removes whitespace and comments). It creates an 80k Javascript file. We were then able to shrink this file to 14k using gzip/mod_deflate. We used a popular, and very efficient, Javascript packer at (http://javascriptcompressor.com). It was able to reduce our uncondensed code from 150k to 43k. So the savings was much better using gzip/mod_deflate and it also does not require a window.eval in the runtime which makes it faster. We even tried running the packed Javascript code through gzip/mod_deflate and it only compressed it to 15k. So there was actually a 1k improvement by skipping the Javascript packer step and simply using gzip/mod_deflate. Only downside, you have to have access to the webserver to use gzip/mod_deflate.

Comment by wgyouree — January 26, 2008

Ah, the Javascript compressor at (http://javascriptcompressor.com) uses the Dead Edwards algorithm.

Comment by wgyouree — January 26, 2008

I think their needs to be a distinction made between obfuscated, packed/compressed JavaScript.

Dean Edwards’ Packer 3 and other compressors can pack as well as obfuscate. If you use the “Shrink variable” option without the “Base 62 encode” option then the code has its whitespace removed and variables shortened but it is not obfuscated (no use of eval()).

The “Shrink variable” method combined with gzipping usually produces the smallest file size so there is no need to use obfuscated compression.

Also, I believe (http://javascriptcompressor.com) is a web port of Dean Edwards’ Packer 2.

Comment by jdalton — January 26, 2008

I think that wgyouree has the right idea.

Aggressive packers introduce needless complexity and the potential for nasty hidden bugs (due to js’s acceptance of implied ‘;’ at the end of some lines, programs break when you remove “extra” line breaks, variable/method name replacement and reduction greatly magnifies the chance of namespace collisions in the js global scope). Stripping comments and then applying gzip will give your users a small download size without potential side effects.

Additionally, packed code is difficult for others to read and understand. A big part of the rapid spread in advanced js techniques that we’ve seen over the past 3 years can be attributed to this informal channel for the distribution of programming knowledge.

Comment by lexander — January 26, 2008

> Aggressive packers introduce needless complexity

It is not needless if it reduces download time by 70% for large scripts. Now that gzip can be used more safely, base62 encoding is not usually required. But to say that it is needless misses the point a little.

Comment by deanedwards — January 26, 2008

@lexander – I agree with you on the semi colon complications, however I don’t think variable namespace collision is an issue as most variable shrinking doesn’t affect object properties or method names. If you use variables in a global scope you are asking to get burned.

When producing a professional client-side we should be concerned with code footprint not readability. The average web user is not going to read the code, but will notice when a page takes longer to load or is unresponsive. The individual developer is responsible for releasing a separate open source or reader friendly version for developers that is not compressed or packed.

Comment by jdalton — January 26, 2008

There are really bad security problems with modern web architecture. This is not one of them. If the minifier is not injecting badness into your code, then there is no reason not to minify your own code. It is reasonable to say that you should not trust obfuscated third party code, but it is equally trust to say that you should not trust third party code that is in the clear. The browser does not give us a way to benefit from third party code without unacceptable risk. These so-called security firms that put out these alarming reports that offer bad advice are making matters worse. I wouldn’t have thought it could be possible to make things worse.

Comment by crock — January 26, 2008

@jdalton -

If you use variables in a global scope you are asking to get burned.

Packer does not shorten variable names in the global scope. I doubt that the YUI compressor does either.

Comment by deanedwards — January 26, 2008

@deanedwards – that’s good to know :), I wasn’t asserting that the compressors did shorten global variables, merely stating that the global scope is normally not safe from collisions, regardless of obfuscating/packing.

Comment by jdalton — January 26, 2008

This reminds me of a thing I found using one of the popular personal firewalls out there. It was removing the outgoing HTTP accept encoding header so that servers wouldn’t return gzipped data. Probably due to some lazy developer didn’t want to add proper gzip unpacking support to their product. But unpacking JS code that uses the packer algorithm is a whole other ballgame since you need a JS runtime in order to evaluate the script so I can see why that’s a bigger problem. But on the other hand some of the machine code analyzers out there for anti virus programs are pretty complex.

Comment by Spocke — January 26, 2008

@Spocke – That’s what I think. Packer is not exactly a sophisticated algorithm. The source code is available. There is even a decoder built in to the online version. Decrypting packer code is not rocket science. It makes me wonder about these security “experts”.

Comment by deanedwards — January 26, 2008

I think the statement that eval is evil is way too misunderstood. That’s the kind of generalization that should only be directed to old-school JavaScript programmers, and should be mocked at by seasoned Ajax programmers such as ourselves.

Comment by Jordan — January 26, 2008

I like the idea of packer and related JS-based compression scripts, particularly for people who may not have the ability to configure gzip etc. Whitelisting packer-based scripts is asking for trouble; instead, a JS runtime should eval script and observe its “execution lifecycle.” This might seem complex, but I think it’s the way things are headed. (UPX in WinPE .EXEs as a good historical example, I see malware distributed with it still today.) Presumably signatures and/or URL identifiers would be other methods, if not already used.

Comment by Schill — January 27, 2008

I forgot to mention – some examples I’ve seen in the wild using packer etc., go like this (here’s the recent SQL injection-based attack one)..
injected on the “hacked” site writes out an iframe which points to an HTML file containing:
 

 
These are the individual exploits, basically copy-and-pasted proof of RealPlayer / Yahoo! Messenger DLL proof of concept exploit code (open + save arbitrary URL to c:\, etc.), complete with comments and everything from the sites publishing them – the catch is that these are doubly-obfuscated. First, they are compessed with Packer or something similar, and then the eval()ed result of that is a large document.write(unescape(bigAssString)) call, where the latter is some concatenated thing of escaped characters.
 
This I believe was used in exploit code hosted on “uc8010″ (dot com), related discussion at sans.org. I wasn’t able to quickly find any sample code, sorry. ;)

Comment by Schill — January 27, 2008

Sorry, the script got stripped out from above – should be:
script src=06014.js
script src=real.js
script src=07055.js
script src=yahoo.js

Comment by Schill — January 27, 2008

A developer describes something technical as bad, wrong or evil either because of laziness or ignorance. The article should have been titled “The Packer 2.0 Non-Threat” because what Don Jackson is saying has very little to do with security or any real threat for that matter.

Cows eat grass, Grass is green, Therefore cows are green.

Malware authors use packer on JavaScript, Packer obfuscates JavaScript code, Therefore JavaScript code obfuscated with Packer is malware.

This article was just written to get a rise out of people. So to sum this all up:
If you can use mod_deflate or mod_gzip then do so. If you can use Packer, YUI Min, or JSMin in your caching engine or in your build scripts (i.e. Ant) then do so. Don’t let untrusted sources gain access to your client’s code repository. Happy coding!

Comment by Tobius — January 28, 2008

I think the article kinda has the wrong name, instead of “The Paker 2.0 Thread”, it should be “We are lazy, please don’t pack your scripts since it’ll be more work for us.”

I mean, seriously, do you ever hear antivirus vendors complaining about UPX and all the other executable compression techniques used? Well, except for Norton and a few others who, once upon a time, decided that all packed .exe’s were evil (and strained their telephone-support department as a result), most vendors accept that it’s just one more variable they have to deal with.

It’s up to the developer(s) of a software package to deliver a high quality product. In JavaScript terms, that also means that it should have a low footprint (as evidenced by tests that the cache isn’t nearly as much used as you would have liked).

Besides, the single most important reason JavaScript developers use a packer is not because of it’s packing techniques (it’s quite feasible to compress without packing; gzip anyone?) but for it’s obfuscation techniques. You don’t want some scriptkiddy mangling your code and posting the mangled code everywhere. Knowledgable people with (perhaps) ill-intent can de-obfuscate the code anyways. If they can do it in two or three steps, it shouldn’t be too hard to automate the process.

So no, packing code does not provide a security threat. In it’s most extreme form (eval), it does use extra processing power on the client. But that’s another discussion alltogether.

Comment by DiSiLLUSiON — January 28, 2008

Hmm interesting that none of the comments arguing with the title of the post actually quote the title of the post. It is a question, not a statement.

Comment by Chris Heilmann — January 29, 2008

@Chris Heilmann:

Yes, here. Not at the source, though.

Comment by DiSiLLUSiON — January 29, 2008

Leave a comment

You must be logged in to post a comment.