The best solution is that the code is compiled into bytecode and that it can not be decompiled. In order to understand why this is the best way you need to know how Railo works. Like CFMX Railo compiles from CFML directly to Bytecode. In addition to compiling into Bytecode Railo uses an obfuscator in order to hide/change function names. So From a code that might look like this (in Java):
which will normally be compiled to the following Java code:
you get something like:
This might not make sense to us, but for the JRE it is irrelevant whether an variable is called "cfmlengine" or just "a". They are just labels. So even if you use a decompiler to decompile the bytecode that Railo generates, it won't help you much. Even we at Railo would have a hard time when trying to fully recover a .CFM file from a .class file.
Knowing all this, what does it help us? Let's proceed. Railo offers you two different ways of securing your source code, well in fact it is one but since, as mentioned above it is so safe we did not implement a second alternative. But you can use it in two different ways.
1. Encrypt a single file
If you want to secure a sole file you can just replace it with the corresponding .class file. Yes, it's so simple! Railo knows whether a file is a .cfm or a .class file (even if it's called .cfm). Bytecode files have a certain signature at the beginning of the file.
The class files usually can be found in the WEB-INF folder under cfclasses. Inside that folder each mapping is represented by a folder. You will be easily able to find the file since inside the mapping folder you will see your application directory structure containing containing all the .class files instead of the .cfm files. If you want to compile your mapping just use the compile button in the detail view of a mapping in the Railo Administrator.
2. Use a Railo archive
Railo allows you to convert your application completely into a Railo archive file. This archive is a simple .jar file. It so contains only the .class files of your application. Just check one of the latest blog entries for how to create a Railo archive.
Now having created a Railo archive, how do you use it? Well, you can let the application check at startup whether a certain mapping containing the Railo archive exists or not. Here's the code how to do so:
This call of the
Means that this mapping has been defined in the server administrator. The files inside are not readonly, but the definition of the mapping is readonly in the web administrator. It is a socalled global mapping (like CFMX mappings).
This is the name of the mapping, like "/mapping".
Here you can define the resource path of the mapping, like a directory, ftp directory, amazon s3 bucket, database resource, ram directory, etc. every virtual filesystem railo supports.
This is the archive associated with the mapping. It contains the .class files for the complete mapping (if available).
If physicalFirst is set to true, Railo first checks the resource for a certain file. If it finds it, the file will be invoked. If not Railo checks the archive for the missing file. If it does not find it there as well Railo throws a fileNotFound Exception.
In Railo you can define mappings as trusted. So your core application that does not change frequently might be trusted. The trusted cache can now be cleared in the Railo Administrator.
With archives you have a perfect way of defining a set of files like a certain core (inside the archive) and another set as customizable files. Then you define a mapping pointing at the archive containing the core and Railo takes care of the rest. The core you created is secured and the customizable files are accessible in the file system and can be changed by your customer.
If you want to create a certain mapping /myApplication, you can execute the following code:
<!--- or a mapping to a ftp server --->
Railo checks whether the mapping exists and creates it when necessary. Once the mapping is created (no matter what resource you are using), you can use all file functions and tags, and all attributes that require a file for it. The sole exception is CFVideo since CFVideo needs a local file to be accessed for conversion.