ColdFusion Muse

Certain JPGs Can Crash Your ColdFusion 8 Server

Mark Kruger June 10, 2009 11:41 AM ColdFusion, Coldfusion Troubleshooting Comments (7)

This issue was brought to my attention by Adrian Lynch on CF-Talk. It seems that if you use the new image functions in ColdFusion 8 against certain kinds of JPG images you can actually cause your JVM to crash. If you have code that uses the latest image functions to handle uploaded images you should definitely take note of this post. I cannot yet see how a user might take advantage of this bug to penetrate your server, but a malicious (or even non-malicious) user could easily perform a denial of service attack and cause your CF server to go up and down like Jack LaLanne doing jumping jacks. So if you fit into that category (handling uploaded images using CF 8 image functionality) here's the scoop.

JPG "ICC" Profile

A JPG image has something (optionally) embedded in it called an "image color correction" profile. It is actually a bit of meta data that tells a browser or other image rendering program how to show the image on the screen. To see the profile, take an ordinary JPG and run this code:

<Cfset info = ImageRead(ExpandPath("./sample.jpg"))/>

<cfdump var="#info#"/>
What you should see is the standard "dump" output showing whatever information can be gleaned from the image file itself about what it is and how to display it. Something like this:

struct
colormodel
struct
alpha_channel_support NO
alpha_premultiplied NO
bits_component_1 8
bits_component_2 8
bits_component_3 8
colormodel_type ComponentColorModel
colorspace Any of the family of RGB color spaces
num_color_components 3
num_components 3
pixel_size 24
transparency OPAQUE
height 1780
source C:\ColdFusion8\wwwroot\sample.jpg
width 1280

Notice the "clolor model" structure and keys. I could be wrong but I take that to be the ICC profile. Now it just so happens that there is a bug in the parser for this ICC Profile. Not the ColdFusion parser, but the underlying parser used by the javax.imageio classes - the ones used by CF under the hood to make this "imageRead()" magic happen. Under certain conditions information in the ICC Profile will be parsed incorrectly and cause a buffer overflow. This in turn abends the entire JVM and causes your ColdFusion server to restart.

Sample JPGs

If you would like to test this and see for yourself, here are 3 images that will do the trick for you.

All you have to do is try running the code above on one of these images using JVM version 1.6.0_04 and you will see your server restart. This article on the JDK IMage Parsing Library Vulnerabilities is where I found enough information to draw my conclusions and make my tests.

The Fix

Fortunately the fix is pretty easy. Upgrade your JVM to 1.6.0_05 or above (current distribution is 1.6.0_14). In the newer build of the 1.6 engine this vulnerability is fixed. Now, if you are using CF 8 with JVM 1.5 (as some folks are) I would be interested to know if this issue is relevant. I could be that it only affects 1.6.0 to 1.6.0_04. Perhaps one of my readers would test it find out. Meanwhile, if you accept images uploaded to your server and you are taking advantage of any of the ColdFusion 8 image libraries (like imageRead() above), then you should probably upgrade ASAP. It's only a matter of time before someone uploads an image that crashes your server.

  • Share:

Related Blog Entries

7 Comments

  • Dave Ferguson's Gravatar
    Posted By
    Dave Ferguson | 6/10/09 10:00 AM
    As a quick addition to this. This crash issue also affects CF8 on x64 servers. Since the 32 and 64bit java versions are a little different I am not certain that the fix is the same but it may be.

    --Dave
  • Russ's Gravatar
    Posted By
    Russ | 6/10/09 11:46 AM
    Yup, just tried it and it crashed Coldfusion. I have JVM 1.6.0_04, so I'll have to upgrade to _05.
    Thanks so much for the noticing a problem and providing the fix!!!
  • Russ's Gravatar
    Posted By
    Russ | 6/11/09 12:05 PM
    Just following up:
    I installed Java 6 update 14 (1.6.0_14) and it fixed the problem. Sample images 1 and 2 worked fine. Sample image 3 causes IsImageFile() to fail, which is fine by me.
  • Josh's Gravatar
    Posted By
    Josh | 6/11/09 3:31 PM
    Thanks for the update, I would have been doing some major head scratching if my server started dying, we use that in a lot of new scripts.
  • Charley Ruggiero's Gravatar
    Posted By
    Charley Ruggiero | 6/23/09 4:35 PM
    FYI I still found images where the JVM upgrade doesn't work! After hours of trying everything on the net the only thing I could use to get resizes to work was saving it temporarily as a BMP, and then resaving it to get rid of all the "junk" attached to the jpeg. So code would look something like this......

    <cfset var.oImage = ImageNew(var.oImage)>
    <cfset var.tempName = "#APPLICATION.tempDirectory#\#createUUID()#.bmp">
    <cfset ImageWrite(var.oImage, "#var.tempName#")>
    <cfset var.newImage = ImageRead(var.tempName)>
    <cfset ImageWrite(var.newImage, "#ARGUMENTS.directory##var.theFileInfo.serverFile#")>
    <cffile action="delete" file="#var.tempName#">
  • Nimi's Gravatar
    Posted By
    Nimi | 3/24/10 2:59 PM
    I am facing one issue with multiserver launching on Coldfusion8.

    I have modified the multiservermonitor-access-policy.xml file in the remote host to allow the access from the source host.Then I have added the remote host details and I am getting permission denied in the status line with below error msg.
    Error #2048 url: 'http://wlpv0002.edc.cingular.net:8500/flex2gateway...' Ensure that you have allowed access to this server by
    changing the multiservermonitor-access-policy.xml file.
  • John Scott's Gravatar
    Posted By
    John Scott | 5/20/10 4:02 PM
    I had luck getting around this problem without updating the JVM by making use of CF's imageGetBufferedImage(...) function:

    bufferedImageObj = imageGetBufferedImage(cfImageObj);
    output = createObject("Java", "java.io.File").init(pathToDestFile);
    createObject("Java", "javax.imageio.ImageIO").write(bufferedImageObj , ".jpg", output);