Wednesday, January 02, 2008

Encrypted CFML Templates

Coming back from the 10 days shutdown period that we had at Adobe, I am catching up with the blogs and I read this interesting post by Ray where he mentioned that some one got his cfml templates encrypted and then lost the originals. Hmmm.. that is a situation, I would never want to be in. In case you have not figured it out yet, it is not possible to get back the original source. Let me explain.

Why do we need to encrypt cfml templates? To protect the cfml code and your intellectual properties (IP) in case you want to distribute your CF application. Right? In pre-CFMX7 era, ColdFusion used to have "cfencode" utility which used to encrypt the template which you can then distribute to anyone. ColdFusion used to know how to decrypt that and then how to execute that. However, this was not a good solution as people came up with utility to decode this encrypted file. And THAT means that  your code and IP was not protected at all. This had another disadvantage - template execution was slower as it meant decrypting the template first and then compiling/executing it.

With CFMX7, this changed. ColdFusion came up with sourceless deployment to make it nearly impossible to decode it back to the original source. When you use 'cfcompile' with deploy option, your cfml template is compiled to java byte code (class) but the file in which this byte code is written still retains the same template name. To give an example, if you run cfcompile on "hello.cfm", the output would still be "hello.cfm" but it will actually be java class file. To confirm this, just open one of such encrypted file in a hex editor and you would see the first 8 bytes will be CAFEBABE - the magic number for java class files. This file can then be distributed to your customers. For execution, ColdFusion works smart - when request comes for this template, it sees that it is not a cfml template but a class file, skips parsing and compiling the template, and directly proceeds with the execution.

As you see, there is no encryption and no key involved here. The encrypted file is simply a java class file and I have not heard of any utility that can decompile this class file back to cfm source. Though there are many Java decompilers available which can convert the class file to approximate java source file, it will be a huge huge task to write a decompiler which can generate cfm code for class file. One needs to know how CF does the code generation, know a great deal about bytecode instructions and apply lots and lots of heuristic to get the approximate cfm source. This is definitely not an easy thing to do even if some one breaks open the CF engine to see how it generates the java code from cfm code.

The bottom line is - in case you use sourceless deployment, ALWAYS backup your original source.

7 comments:

Raymond said...

Thanks for this. Just to be clear - this wasn't my code that was encrypted. I'm way too paranoid to not use multiple backups. ;)

Dan Vega said...

Thank you for clearing this up. Everything makes a lot more sense now.

Dan G. Switzer, II said...

Rupesh,

I think this entry is a bit confusing. You can still *encrypt* (not compile) CFM templates if you choose.

I just checked and both CF7 and CF8 still come with a cfencode application that you can use to encrypt the template.

There's even a flag which allows you to specify the version compatibility level you want to use.

Compilation is a certainly a much better choice if you want to protect your IP, but when I read this article it sounded like encryption was no longer even an option--which it is.

Rupesh Kumar said...

Yes Dan. You are absolutely right! We still ship cfencode and it can still be used for encrypting the template and CF can still process such encrypted file. (It hasn't been touched for a long long time though - it only allows version 1 and 2 :-))

However I had assumed that the user here had used 'cfcompile' to encode the file and wants to decode that and thats why I had said that it can not be decrypted back to the original source.

cfencode and cfcompile both are separate and both work differently.
As we all know, there are utilities available which can decode the file encoded by 'cfencode' and hence it is not recommended to be used.

Hope that clears the confusion I created :-)

Anonymous said...

Can you clear up my confusion as to whether this "compiled" code can be deployed on Coldfusion 8 standard? I've heard I can "compile" it with all versions of Coldfusion but that it can only be deployed on coldfusion enterprise.
Thanks much.
SC

Charlie Arehart said...

SC asked (back in March) if code compiled on Enterprise can be run on Standard. I've tested it, and yes you can. (I compiled with CF8 Enterprise and run with CF8 Standard.) I also tested running the same code with CF7 Developer edition, and that worked too.

BTW, Rupesh, any chance you may delete the few spam entries that have slipped in here since then? just trying to help.

Jason Fill said...

I realize this is an older post but hopefully someone can shed some light on a question I have:

One thing I am curious about in using cfcompile is what versions and jre's you can expect the compiled file to run under. For example, if I compiled on CF 9.0.0 using the java 1.6.0_14, would that run under 9.0.0 with java 1.6.0_20? So basically is the Java version or the CF version what can make the compiled file different, or both?

The basis for this question is an application I have that will be distributed to customers. I need to figure out what combination's of compiled code I will need to create for the most compatibility.

Thanks!