Security Checking PHP Templates

WordPress uses PHP as it’s templating language. It’s well established and as I’ve said before, there’s an abundance of free themes out there for it.
Unfortunately in a multi-user environment, allowing untrusted users to edit PHP code on your server is a huge security risk. There has to be some way to limit the commands a user can use, and there is!
PHP already parses html pages, so why not take advantage of that engine? The PHP Tokenizer lets you do just that!
Feed your template through token_get_all() and it’ll spit out an array containing HTML, PHP, and other elements from your file.
Here’s an if statement that should be familiar:

T_OPEN_TAG: '<?php '
T_IF: 'if'
T_STRING: 'have_posts'

We then need to compile a list of allowed functions, which can be got from wp-includes/* and we’re well on the way to a safe environment for WP bloggers. Any more ideas?

Author: Donncha

Donncha Ó Caoimh is a software developer at Automattic and WordPress plugin developer. He posts photos at In Photos and can also be found on Google+ and Twitter.

16 thoughts on “Security Checking PHP Templates”

  1. Man, I cannot agree more with this one. I’m the primary author (thus far) of the WordPress hardening guide at the WordPress Codex, and allowing users to have write access to actual code is a major problem. So you either need to disallow it or contain it. This is a good way to contain what users do. Another possibility is to use chroot with Linux or jail in BSD to segment off sites from each other, though you’d have to be running several WP installations instead of WPMU, so it’s of limited relevance here. Still, even just limiting permissions on the file system would go a long way to providing some containment.

    For WPMU, you could use a similar technique to force the user into only using Smarty for templating if your users don’t need more than that.

  2. This looks like it’s doable. Some themes and plugins will have to be updated or rewritten in order for it to work, and there’s also the issue of plugins which define their own functions. Now who’s going to step up and actually do it? 🙂

  3. WordPress is using CSS extensively and thus the only thing the untrusted user must change is the styles-files. Look at CSS Zen Garden, they don’t change the HTML at all.

    A good idea would be to seperate the css from the rest of the theme but keeping the classes and ids.

  4. @TomK32: Yes, the stylesheet is one part of the theme, but there are also PHP files in the theme that can be modified. This is a big part of WP themes, and theming would be limited if users couldn’t modify the theme files.

  5. I agree totally with stripping the ability to use Javascript and PHP within posts, but stripping inline CSS? What could possibly be used in CSS inline styles that would be a security risk? If there is such code, then can’t those be filtered out, leaving the ability to add spans of color, font-size, or a little border?

  6. I was gettign ready to download wordpress and try multi, but then read this post. Need to know if it is feasible for me to do mu without having all the potential problems mentioned? Is there a way for other users to have limited ability to change themes/templates? A way where I don’t have to deal with the issues described. In other words, basic use of themes/templates?

  7. djinz – I don’t know. I haven’t spent any time at this problem since and if you’re a user you’ll know that we don’t yet allow editing of templates. It’s a difficult problem to solve.

  8. I just about lost a mouthful of my coffee when I read this. Allow arbitrary persons to write PHP – but only ‘good’ PHP. Why not just give them root access? Heck, wouldn’t life be easier if we just gave everybody our database login? Then they could not only change the theme, but even make the content match it… I’ve got a really cool theme idea – I call it ‘black nothingness’.

  9. Instead of asking yourselves whether you should offer your WPMU users the ability to edit templates and themes, you should ask whether a user who is on a system such as WPMU (which I equate with TypePad or Blogspot) would even care to go through the trouble of doing so. In other words, if they care so much about tweaking templates and themes, then they should just spring for the hosting and a domain and be done with it. You can’t have your cake and templates too!

  10. As I logged in the first time in I was a little bit disappointed that I can only choose one of those themes and that it is not possible to customize them. I spoke with some other people I have invited to and they, too, were disappointed about that point. But I understand your problem with that.

    But I agree with Joni on this point. The people I spoke with just want to edit the colors of the page and some standard things. They don’t have a clue about PHP and they don’t want to take care about that. They are used to xanga and other services where they can adjust some elements of the pages without thinking about the code. If someone wants to play around with templates in the source he has to install it for himself on a server.

    The most important things for most of the “standard” user out there are in my eyes:

    1. Change the header Image

    2. Change the colors

    3. adjust the elemtents in the sidebar (the order of the parts there, what shall be activated, display link categories or make it just a big blogroll [some of the themes do it one way, some other do it otherwise. So if I want to display link categories I eventually have to choose a theme I dont like. Unify it and many people will be thankful])

    and 4. If you don’t allow customizing the templates in the source then include many themes, and especially many different themes (not just the standard “sidebar-content” “content-sidebar” layout, but some other kinds of blog layouts), and this would make most of the users satisfied, I am sure.

    But as I have followed the discussion about on this point correctly, then your are on the way to make it similar to what I descrided here. And I think this will solve most of the problems.

    Wpmu is a great piece of software. Your are doing a good job on that and I am sure you’ll find a good solution for that problem.

  11. Hi,

    Well I was wondering, editing a template at the source… wouldn’t this take effect on all users who use this theme? (me noob)

    Also I agree with Joni here, most users will want to edit things like colors and are too noob with php to do serious damage (I think). But hell, you cannot be too careful these days….

    I have two solutions/ ideas:

    1) Editing templates can only via WYSISWYG kinda way, like Frontpage and Dreamweaver have in their design mode. Easy color changing, selecting colors form a color table etc. Drag and drop sections in sidebars to change their level of appearance and so on.

    Sec option:
    Rrestrict some commands. Like is done with replying here:
    HTML allowed:

    So make it: PHP allowed etc etc, should take some security risks away.

    Just my 2 cents


  12. I agree on what most of the user’s have said. But before I had come across MU, I was about to write my own system making use of different installations which could hurt the server space. Well, for such system I was using a security check to disallow certain functions which can cause issues.

    I think the least feature available should be the abilitiy to customize the CSS which should vary on EACH theme because there aren’t any standards setup. If some standards are setup and all themes follow the same pattern, it would be easier to make the CSS stylesheets editable in a visual environment (letting users choose colors for different parts).

    Probably, another nifty feature would be to allow users change the header picture. I don’t think many users care to do more than that. And please, I am talking from experience. Most of the bloggers are newbies or they don’t care to go with a service using WordPress MU.

    One more thing I would like to Highlight and which is very necessary is the normal user registrations like in normal WordPress. I know it defeats the point of saving space when using multiple tables for users, but it is kinda very necessary. Many users want to allow others to register and getting a blog just to register doesn’t sounds good to me. Instead you could use following pattern:

    – Different user table for each blog.
    – On users page in admin cp, for adding from network, it can probably interact with the main users table.
    – If an existing blog owner wants to register on another blog on the network, he can probably do that with one click.

    Sorry, I know I went a bit offtopic, but I hope it gets seen by donncha.

Leave a Reply