Laravel is a popular PHP framework but how do you encode a Laravel project? This post covers using the ionCube Encoder to protect a simple Laravel 5 project by encoding the Laravel controller and model files, encrypting the Laravel Blade templates.
The project in this example is based from:
and is using Laravel 5.3.
Download code for this example
The tutorial gives:
- A MySQL table called cars with the columns “make”, “model” and “produced_on” and with one record within the table.
- A CarController.php within app/Http/Controllers
- A Blade template show.blade.php within resources/views/cars
- An added route within routes/web.php
and produces the following output in a web browser.
The project code is shown below, and is also included with this guide.
Protecting Controllers and Models (Basic Encoding)
Below are instructions on how to encode your Laravel framework project. When completing these steps it is crucial that the parts of Laravel applying getDefaultValue() and isDefaultValueAvailable() are encoded (See point 2 at the end of this section).
When it comes to encoding the project files, if the CarController.php controller is encoded and no obfuscation is used, the Laravel project will work as expected.
The general form for encoding is:
ioncube_encoder [options] [source directory] -o [target directory]
For this example, the project is installed in /var/www/html/project and is encoded to /var/www/html/project_encoded. The Encoder command to do this would be:
./ioncube_encoder.sh \ --copy "@/*/" \ --encode /var/www/html/project/app/Http/Controllers/ \ /var/www/html/project/ -o /var/www/html/project_encoded
As we want to encode just the controllers directory, the ––copy option is used to tell the Encoder to copy all PHP files rather than encode, followed by the ––encode option to encode the controllers directory. Models could be encoded using the same method.
More recent versions of Laravel apply reflection to the user’s classes and methods. In particular, it uses the getDefaultValue() and isDefaultValueAvailable() reflection methods on the parameters of the user’s methods. Due to the way that those reflection methods work in PHP, they will fail on our protected byte code. That’s because they look for particular byte code instructions which will not exist in the encoded byte code.
However, if the part of Laravel that applies those methods, getDefaultValue() and isDefaultValueAvailable(), is encoded then the Loader can intercept such calls and apply ionCube’s version of those methods to the user’s methods.
To do this, you must complete the following extra steps:
- Ensure that your own classes and methods are encoded with –allow-reflection-all which, in the GUI, is the “All” setting below “PHP functions that reflection methods can query” in the Project Settings Keys tab.
- You must encode the parts of Laravel which use getDefaultValue() and isDefaultValueAvailable(). The easiest way to do that is to encode all of the Laravel framework. You must ensure that you do not *encode* any blade template files, however. Blade template file *encryption* is covered in the next section but this is an optional step.
Encrypting Blade Templates (optional)
Laravel Blade templates, despite having the file extension .blade.php, are not pure .php files, and can contain Laravel specific syntax that Laravel expects to interpret. The Blade engine reads the contents of templates, processes any Blade syntax, and produces a final PHP file. The Encoder will normally encode anything ending in .php, so a .blade.php file would be encoded in the same way as any other .php file. With the template encoded, when viewed in the web browser the application now produces:
This is because Laravel will not see any Blade syntax as the file is encoded, however there is a solution.
The ionCube Encoder can also encrypt non-PHP files, and unlike encoded files, encrypted files can be decrypted back to their original contents by using an API function in the ionCube Loader. Blade templates can be protected using the encryption feature whilst still allowing them to run, provided that a small change is made to the Laravel core to decrypt when required.
Within the Laravel core the BladeCompiler.php needs to be edited so that it can decrypt ionCube encrypted files. The compiler can be found at:
Within the function compile the code needs to be changed, as seen below.
The ioncube_read_file() function decrypts the Blade template so that it can be interpreted by Laravel before being passed to the browser. The ioncube_read_file() function can only be used within an encoded file so BladeCompiler.php will need to be encoded. When successful, ioncube_read_file() will return a string with the decrypted contents. However, it will return an integer if an error occurs (see section 6.5 of the user guide for error codes.)
The ––encrypt option can be used to specify files or directories to encrypt, so encrypting the templates can be done using the command:
ioncube_encoder –encrypt ‘*.blade.php’ [source directory] -o [target directory]
Specific to this example it would be:
./ioncube_encoder.sh \ --copy "@/*/" \ --encode /var/www/html/project/app/Http/Controllers/ \ --encrypt '*.blade.php' \ --replace \ /var/www/html/project/ -o /var/www/html/project_encoded
Note that the ––replace option is also used, and tells the Encoder to replace the already existing output from the first encoding.
More information about the ioncube_read_file() function can be found in section 6.4.1 of the user guide.
To conclude, you can encode a Laravel project, however simply encoding the whole of your Laravel project won’t allow the project to run as desired. The Laravel core is opensource so doesn’t need to be encoded. To encode a project, follow the simple steps below.
Encoding the project
- Encode the controllers and models
- Encrypt the Blade templates
- Edit the BladeCompiler.php to decrypt ionCube encrypted files
- Encode BladeCompiler.php
To include obfuscation within your project: ionCube Encoding a Laravel Project: Function Obfuscation