Polyscripting WordPress: using scrambled PHP to stop code injection attacks

When Polyverse announced Polyscripting a few weeks ago people were quick to point out that the idea wasn’t fully, well, developed. That’s because it wasn’t. But what was then an introduction is now a usable tool. We’re back with a Polyscripting update: Still being improved, still being developed, but with a substantial use case. Especially given the recent PHP vulnerability report.

First, let’s talk about WordPress.

Regardless of how you feel about the website creation tool or PHP for that matter; it powers 26% of the entire web. WordPress is by far, without competition, the most used CMS in the world with more visitors per day than Twitter. For better or worse, people are using it. A lot.

For the purpose of this article, the take away here is this: there are millions upon millions of WordPress websites, and they’re all using PHP.

Vulnerability Warnings in WordPress and PHP Docker images

Just last month a PHP vulnerability was disclosed that allows malicious actors to inject their own code into a WordPress site. A vulnerability that, despite being known for over a year, has yet to be addressed and fixed by PHP or WordPress. In fact, the Equifax Breach, one of most damaging hacks in recent history, was largely possible due to a similar vulnerability. At Black Hat this year, research was introduced that suggests these vulnerabilities that are labeled “low-risk” can actually expose your website to considerable dangers. That, of course, is the interesting thing about cybersecurity and software vulnerabilities: we often get it wrong, priorities change, and hackers get more creative. We build fixes issue by issue, but that does nothing to mitigate the risks that we don’t yet know about or remain unfixed.

Enter Polyscripting. Rather than focusing on and fixing individual vulnerabilities, why not render entire attack vectors impossible? Polyscripting assumes vulnerabilities exist, and that there are ways, known or not known, for someone to get malicious code onto your server, and to then execute that code. So Polyscripting focuses on that; the attack vector as a whole. Polyscripting creates a unique version of PHP for the specific instance of a specific WordPress site. If through some means a hacker is able to inject unwanted and malicious PHP code into a WordPress site, it won’t be recognized or be able to be executed. It will instead result in a syntax error.

Launching WordPress with Polyscripted PHP in docker container is incredibly simple, and for those used to launching WordPress with Docker, the changes are trivial.

Building a Polyscripted WordPress Docker Container

To build out Polyscripted WordPress for this demo you’ll just need Docker. That’s it. Let’s walk through how it works.

First, a quick overview to demonstrate Polyscripted PHP in action. Clone Polyverse’s open-source Polyscripted WordPress git repo.

git clone https://github.com/polyverse/ps-wordpress.git

From that directory run the command:

$ ./build.sh; ./run.sh

Navigate to localhost:8000. You’ll be met with typical, normal, and familiar WordPress that is now running within the container. Pretty simple stuff. For all you know, this looks and feels just like normal WordPress. That’s exactly how it should be. For the sake of demoing Polyscripting, we could stop right here. You are now using Polyscripted PHP but for the user’s (and your) perspective, behaves no differently that WordPress using standard PHP.

But that wouldn’t be an exciting demo, so let’s break it down. To see the effects of Polyscripting, exec into the new WordPress Docker container and check out the scrambled source code.

$ docker exec -it wp-cont bash
$ vim /var/www/html/index.php

The file will look something like this:

All PHP keywords have been replaced with randomized strings. Yet WordPress function normally because these strings are the only recognized version of these keywords.

There it is. This WordPress container is running using Polyscripted PHP. A completely unique version of PHP that will only ever work with this instance of PHP and the matching source code.

For an example of what this protects against, insert some standard PHP within this file and save it. Then navigate to localhost:8000/index.php on your browser.

After I added

echo "Hello World";

into the index.php file I was met with:

Parse error: syntax error, unexpected '"Hello World"' (T_CONSTANT_ENCAPSED_STRING) in /var/www/html/index.php on line 12

PHP code that was not passed through the scrambler (which I’ll talk about in a minute) will be able to run because the PHP interpreter that Apache is using does not recognize standard PHP keywords. Meaning any malicious backdoors or other injected code will log a syntax error rather than execute. Also, every time you rerun this Docker container the PHP scramble will be totally unique to that instance within that container.

Adding Polyscripting to your Own WordPress

So now let’s dive down into what is actually happening, and how to add your own WordPress files to the container.

  1. From the directory you pulled earlier, replace all necessary files within the WordPress subdirectory with your own site’s source code. If you want to change the theme only, replace the files in wp-content/themes/mytheme/ with your own files. Note: if you want vanilla WordPress, no changes are necessary, you can safely skip this step.
  2. Open the Dockerfile. It should look something like this:
FROM polyverse/ps-php-apache
COPY ./WordPress /usr/src/wordpress
COPY scripts/* /usr/local/bin/
RUN scramble.sh
WORKDIR /var/www/html

Notice this file contains only a few Docker commands. Here’s a quick explanation. The only difference between this Dockerfile and one that runs WordPress with normal PHP is the FROM command and the RUN scramble.sh. The ps-php-apache docker container configures Polyscripting capabilities to the official WordPress docker-library container wordpress:php7.2-apache(the git repo for ps-php-apache can be found here). If you were building this without Polyscripting the FROM command would be FROM wordpress:php7.2-apache.

The Dockerfile then copies over the WordPress source and a couple of scripts. scramble.sh is the script that will actually scramble the PHP interpreter, give that PHP version to Apache, and scrambles your WordPress source code. This will create a completely unique instance of Polyscripted PHP that only works for this instance of your WordPress.

And that’s it. No steps are necessary here on your end, just a quick explanation of the process.

3. Now, you can build and launch your Docker containers. First, a MySQL container, and then an apache container running your WordPress site. The commands for building and launching these containers are within the build.sh and run.sh scripts. So you can simply run build.sh then run.sh after the build completes.

$ ./build.sh; ./run.sh

Or if you prefer, run each step individually.

#build container
$ docker build --no-cache -t wp-image .
#Start mySQL container
$ docker run --name mysql-cont -e MYSQL_ROOT_PASSWORD=qwerty -d mysql:5.7
#Start apache/WordPress
$ docker run --name wp-cont --link mysql-cont:mysql -p 8000:80 wp-image

The first command builds the WordPress docker image. During this step, the PHP source and interpreter is scrambled (this happens within the scramble.sh script that was mentioned earlier). The next two steps start a linked MySQL container and WordPress container respectively.

This process can also be simplified by using Docker Compose and the YAML file already in the repo by running a single command:$ docker-compose up -d --build

4. Access your apache server at localhost:8000 in your web browser. WordPress looks and feels identical — because nothing fundamental about WordPress has changed. You can build a site, explore, and design just as you would normally. The only difference you’ll notice is that plugins cannot be installed. They must be installed before the Polyscripting takes place. More on that at a later date.

Note: Any PHP changes should be done without Polyscripting turned on, and scrambled after (i.e. plugins).

Of course, this is a starting point. You can still customize and configure your WordPress site and MySQL database. Feel free to play around, add to the functionality and leave us thoughts and feedback on the public Polyscripted WordPress repo or the polyscripted-php repo.

What’s Next

The reason we chose PHP to be the first Polyscripted language was largely due to WordPress and other content management’s sites popularity. PHP has a far reach across the web, with millions of users accessing websites that use it every day. There are web developers, programmers, bloggers, and companies currently relying on the language to run and protect their websites and to interact with their databases. Regardless of criticism or blaring security vulnerabilities, PHP is a frequently used and vulnerable server-side language. This was the perfect place to start to show the potential and power of Polyscripting. A WordPress site that uses Polyscripted PHP is protected against Code Injection, regardless of the specific vulnerability that allows code to be injected.

That being said, WordPress is only the first of many sites that can benefit from this kind of protection. Polyverse will continue to apply the technique to other similar use cases. However, first, we plan on making the transformation process that Polyscripting uses more robust. Rather than using PHP’s tokenizer class, we will transform the source code to the matching Polyscripted dictionary directly from the Abstract Syntax Tree that the interpreter itself uses. This will also allow us to eventually scramble not only the lex portion of the interpreter (the words) but also the grammar of the language (the syntax). It will also allow us to scramble built-in function names such as strlen() or get_current_user().

The goal is to make Polyscripted PHP as unique as possible per instance. Though it will always be built from PHP and behave like PHP, the goal is to make it look like something completely unique. It is noteworthy though that unlike obfuscation, Polyscripting doesn’t just look unique and confusing, but is possible to undo or decode. The fundamentals of the language itself are what is being changed, the interpreter will only understand the specific scrambled version of PHP, and nothing else. It is not just a shroud of confusion, it creates a language unique from the original language upon which it was built. A PHP interpreter that can only interpret matching scrambled source code.

As we grow out open-source Polyscripted PHP we continue to have our sights on other languages with similar kinds of vulnerabilities. Polyscripting could not only protect WordPress, but make SQL injection attacks impossible, and stops the possibility of widespread and damaging Code Injection hacks like Equifax.

Want to learn more about Polyverse?

Sign up below and receive our monthly newsletter in your inbox.

The registered trademark Linux® is used pursuant to a sublicense from the Linux Foundation, the exclusive licensee of Linus Torvalds, owner of the mark on a world­wide basis.