Please stop the FUD about WordPress.

I came across this posting from a web services company with a brief comparison of different cms options.

Craft — Very secure

WordPress — Can be difficult to secure properly (frequent vulnerabilities due to popularity)

Drupal — Very secure

Clients and co-workers come in with this “wordpress is insecure” opinion largely because of misinformed opinions from “experts”.

Better summaries for their security would be;
Craft – So far; secure with regular updates and careful plug-in selection.
WordPress- Secure with regular updates and careful plug-in selection.
Drupal – Secure with regular updates and careful plug-in selection.

Lets look into that a little bit; shall we.

Craft CMS
They do list all the security best practices they engage in which is great.
The Common Vulnerabilities and Exposures database has 11 reported issues with “Craft CMS” since 2017 with 3 in 2019. It doesn’t look like they engage in any kind of project level security review of this code. While I’d say given that low number of issues it probably deserves being called “secure”; more expert eyes looking in a regular way would be better.
They do benefit from the efforts of the Yii2 project its built on and aren’t likely to experience issues with any of their components. It’s smaller ecosystem than say Symfony but still relevant.

A quick search of the CVE shows that plug-ins and themes are 99% of all the WordPress related vulnerabilities. WordPress core had 11 reported vulnerabilities in 2019. The WordPress core has security team which reviews its code base. It’s active user community reported most of those; not its security team. The push button nature of WordPress updates is its greatest feature. I’d have no trouble trusting a client to apply updates to their site which to me means its likely more secure than other options.

I’d argue that Drupal is less secure than WordPress.
11 vulnerabilities were reported in Drupal in 2019. Plug-ins are also the majority of their issues. Drupal also has a security team which is constantly reviewing its code base and its most popular plug-ins. With version 8; they’ve chosen to use standard components provided from the Symfony project which should eliminate a lot of their potential security issues with core components. Updates are still a pain point; although its much better in version 8. Updates are often more complicated than pushing the “update button” I’d wager that your average client isn’t going to do that very often.

And while we’re on the topic.
The section on “License” is misleading.

Craft is offered under the “Craft” license. It is proprietary open-source software.
You can’t run it without a license and should pixel and tonic go out of business; you won’t be able to run craft.
(Granted; that will likely never happen but it could.)

WordPress and Drupal are licensed under the GPLv2 license. This is free (as in freedom) open-source software which can be used for derivative works.

I likely put more though into this posting than the original author. I understand the demands of making materials accessible to a client but I’m also tired of folks bagging on WordPress. I love php and for better or worse; WordPress is really why we’re still talking about php in 2020.

Stepping down from the soapbox now.

I love Cockpit CMS

I've had a lot of fun playing with Cockpit CMS.
It's a "An API-driven CMS without forcing you to make compromises in how you implement your site."

Its a CMS without a front end. The front end is completely up to you. This tool takes care of all the back-end stuff. It provides a UI for building content types, uploading media, editing media and content, doing site backups and authentication. How the data is displayed is entierly up to you.

Built with a custom microframework called "Lime" which looks alot like slim2 and a storage system called "Mongo lite", it provides everything you need to build small sites that are a joy to work with.

The documentation includes a walk-through on how to build a simple blog.

Working with Legacy PHP

I support a legacy application and have recently begun making modifications to this code base. Creating a dev environment for older php can be a beast. This wouldn’t have been possible without vagrant. Here are some tricks I discovered while setting up my php 5.2 dev environment in 2016.

Did someone already do this?

I found

In my case, I don’t want the entire environment inside vagrant and had trouble with some of the configuration decisions of these boxes.

They were really specific to testing wordpress.

Configure Vagrant

Mine is based on bento/centos-5.11

It was the most popular centos 5.x box at the time.

This image doesn’t have apache or php installed by default.

Edit the Vagrantfile and enabled the local networking.

This gives you a consistant ip address each time you start your dev environment. “private_network”, ip: “”

Increase the memory alloted to vagrant box. Look for this near the end of a “standard” vagrant file.

  config.vm.provider “virtualbox” do |vb|

# Display the VirtualBox GUI when booting the machine

vb.gui = false

# Customize the amount of memory on the VM:

vb.memory = “1024”


I added a line to start apache after the box finishes starting up. ( This is at the end of a “standard” vagrant file. )

In my setup. The apache config for my virtual host is a part of the applications code repository.

This caused problems because apache was failing to start because vagrant hadn’t mounted my shared folder yet.

config.vm.provision “shell”, inline: <<-SHELL

sudo /etc/init.d/httpd start


Installing php 5.2 in 2016

Your options are find rpms or compile from source. I tried the ‘compile from source’ route and it didn’t go so well.

There are a number of libraries that php depends on that have been updated and are no longer compatible.

hense the php52-backports project. I was able to compile but had trouble building an apache module.

It was much easier to find RPMS.

I used iworx-unsupported repo. It was referenced in many spots and was only missing one plugin I needed.


name=IWorx Unsupported



/etc/yum.repos.d/iworx-unsupported.repo (END)

It does not have an xdebug module so I had to install that via the pecl repository.

yum install php.x86_64 php-cli php-soap php-devel php-mysql php-pdo php-mcrypt php-mysqli php-pear php-gd php-devel gcc gcc-c++ autoconf automake unzip zip

Can’t mount folders in vagrant after yum update

Running yum update will probably break your box’s ability to mount shared folders.

To fix; you’ll need to rebuild virtualbox’s guest additions.

sudo /etc/init.d/vboxadd setup

Installing old xdebug

Version 2.2.7 is the last version which supported php 5.2

If you use pecl to install and build the module, you’ll get the latest release which doesn’t support php 5.2.

We’ll have to compile this module manually.

You will need to install gcc, gcc-c++, autoconf automake php-devel and php-pear.

mkdir /opt/xdebug

cd /opt/xdebug

wget –no-check-certificate

tar -z -x -f ./xdebug-2.2.7.tgz

cd ./xdebug-2.2.7


./configure –enable-xdebug


make install

My xdebug config looks like this:



xdebug.remote_enable = 1

; default for vagrant

xdebug.remote_host =

Since we configured a static address earlier, we can now use that address with xdebug.

I was so happy the first time phpStorm started a debug session with this app. Screaming and clapping.

Connecting to local MySQL

I’m used to using my local mysql instance for development. Having it virtual box with all the constrants of virtualbox is awkward.

I wanted to connect my virtual box guest to a mysql server running on the host.

If are ok with mysql running on all your ip addresses, then you can just use the same address you used for xdebug. Edit the /etc/my.cnf to allow connections from and you’re set. In my case, mysql only runs on localhost.

We can still connect it to the guest via a ssh proxy.

vagrant ssh — -R 3306:localhost:3306

As long as the command prompt is open, your guest will be able to use the proxy.

I think that covers all the gotchas encountered while trying to configure my dev environment for old php.

PHP 5.2 has been unsupported since Jan. 2011, but a dev environment is the first step to modernizing this app. From a breif test on php 7, I’ll have plenty of work to do for years to come.


mod_mime + php = hacked site.

So I learned something about mod_mime today that made my jaw drop.

The default way of telling apache to parse a php file looks something like this:

AddHandler php5-script .php

If you install php via the command line on RHEL 4,5 or 6, this is how it sets it up.

What I didn't know is that mod_mime expands the match (.php) to anywhere in the file name.
So test.php or test.php.csv or test.php.jpg would all be passed to the php handler to be executed.


That's a big deal when your application accepts file uploads and is only type-checking the last file extension.
Magento, expression engine, wordpress, etc…

The workaround is to only apply the php handler to files which end in ".php"

<FilesMatch \.php$>
    SetHandler php5-script

And for a little extra 'security', disable php for a directory if you're accepting uploads.

<Directory "/var/www/html/example/uploads">
    php_flag engine off

Which I'm going to go back and change on any server I've ever setup.
I learned this tid-bit from a security advisory from magento.

UPDATE: You may also see a lot of folks who recommend turning on "open_basedir" in php to lock thinks down.
There is a cavet there too. When "open_basdir" is in use, php disables the realpathcache. 
This makes loading/including files very slow.

php has a ftps bug, please vote this bug up so someone will approve this patch

Update: This fix was finally merged into php 5.6 and 7.0 in Dec. of 2015. It had 165 votes! Thank you for support.

Setting up an FTPS server securly is a big pain. If your environment is behind a NAT, sometimes the server doesn't even know what its public address is, which makes enabling PASV mode fun!

I'm trying to connect to a server setup like this and when I enable PASV mode, it responds with an unroutable internal address.
FileZilla works around this issue by ignoring the address and using the servers inital address instead and everything works as expected.

PHP's FTP library does not. It happily accepts the unroutable address and ultimately fails to connect moments later.

This guy knows what I'm talking about and actually patched php to fix this bug.

If you have a moment, please vote this bug up so it makes it into php's next offical release. 
It was reported in 2011 in version 5.3 and is still unassigned.