98

I have seen many times people saying not to use custom PHP/PHP filter (from the Drupal UI) in blocks, nodes, views-args, rules, etc. I have searched around a bit and haven't found much, it seems like this is a Drupal best practice that all "just know".

I understand it poses a potential security risk especially in the hands of end users or people new to Drupal or PHP, but as a developer/site builder what are the real reasons to not use custom PHP from the Drupal UI?

1
  • 1
    As usual, it depends on the situation! If you just require a basic print $block on the bottom of your Views page in a 'views footer', it might be ideal to just do it via the gui compared to writing up a whole entire tpl file just for that purpose. This of course also depends on the role of the site and other factors: Tight deadline? User community site? Or just informational site? Is it a vital to business operations? etc... depends. Jan 15, 2015 at 23:11

7 Answers 7

131

Some reasons:

  • Code in your database can not be version controlled and is also harder to find in general later on.
  • Eval()'d code is much slower than something hardcoded in a file.
  • If there is an error somewhere in that code, you will get a very unhelpful error message (error in eval()'d code at line 3) and you might even have go through your database manually to find and fix the error. If it is inside a block that is displayed on all pages and results in a fatal error all the time for example.
  • The above is also true when upgrading from Drupal 6 to 7 and whatever API's you used were changed. So you will have to port your code while migrating. If the code is in a module, you can port it in advance, test it, and only deploy it on the new site. Inside a node or block, it will only work with either Drupal 6 or 7.
  • Writing and maintaing that code is also harder, because you are working in a textfield inside your browser. Having it in a module allows you to use an editor/IDE with syntax highlighting, autocomplete and so on.
  • There is always the possibility of a misconfiguration that gives people access to a text format/block/whatever with php execution enabled. If php.module (in D7, D6 is not so strict, for example for block access rules) isn't even enabled, that risk is much lower already.
  • If your CMS allows execution of PHP then an attacker who finds a security vulnerability of XSS or privilege escalation can now use your server for enormously malicious things (as part of a DDOS, sending spam, hosting malware, hacking into other sites/databases on the server, hacking into other servers on the network that might be behind firewalls). In addition to making small vulnerabilities more painful, this makes the site a more likely target of attack if its known that it can be used to execute php.

There might be more reasons, but that should be enough :)

5
  • 3
    Nice list:) hopefully will be a resource to others
    – Laxman13
    Apr 20, 2011 at 14:09
  • 3
    @Laxman13: "to others"... and for you too! :D @Berdir: +1, very good aspects. By the way, you don't have to write the whole code in a text field, as you can also include a file there. E.g. you can put just one line in the text field: require_once $_SERVER['DOCUMENT_ROOT'].'/sites/all/themes/myTheme/php/stuff.php'; and write the rest of the code in your IDE/text editor. Sometimes it's not an easy job or would take a very long time to create an own module even as a good PHP-developer. One short example: Ubercart Conditional Actions. But it's true it's not a good thing to keep our code in db.
    – Sk8erPeter
    Dec 10, 2011 at 2:01
  • I mean, e.g. UC Conditional Actions module has a very great GUI which saves a lot of time from having to write our own long codes. You can create a really complex action in minutes with a "next-next-finish" method on a GUI. But maybe you would like to extend the functionality with some of your own codes - in many cases, it's simply not worth it developing a module for that purpose.
    – Sk8erPeter
    Dec 10, 2011 at 2:06
  • 1
    +1000 - I've seen so, so many projects burned by pretty much every bullet point in this list. There was only one time in my entire life that using the PHP module was the only way to get something done in a sane way, and that was only because of an issue with D6 that was fixed in D7. Oct 3, 2013 at 19:55
  • Thanks for your details answer for this question. I found a situation while working in Drupal, that when we need to add link in 'text editor', we need to use php code in 'text filter' otherwise it will not work as expected. Oct 28, 2013 at 9:18
18

This code is difficult to debug and maintain. I don't know any way to use version control for such kind of php code.

And it's really a potential security risk for people new to Drupal or PHP,

1
  • 1
    Well, if the block configuration exported to the code with features modules it is not a problem to put php snippets under version control.
    – ya.teck
    Jul 5, 2015 at 5:36
14

Considering the case of the PHP filter used in a node, the reason not to use it is that you limit the users who can edit that node, if you don't want to allow all the users to use the PHP filter.
Rather than using the PHP filter, it is better to use a custom module that replaces specific text in the node content with the result of the code it executes (without using eval()), or that appends its own text to the body content of the nodes. In this case, any user could edit the node, without to have the permission to add arbitrary PHP code that is then run by the PHP filter.

Generally, it is better to avoid eval() because it decreases the readability of the code, the ability for you to predict the code path (and possible security implications of that) before runtime, and hence the ability to debug code.

Apart in a development or a test site, I would not enable the PHP filter, or use PHP code that is passed to eval().

The PHP filter has been removed from Drupal 8. It is now a third-party module, not covered from the security advisory policy. This is probably a reason more for not using it in production servers (if the already given reasons didn't convince you).

0
11

As a work-around for the various problems specified above - difficulty of code maintenance, version control, error-finding, you have this slightly "klugey" possibility:

Create functions (name them carefully, according to what they do) in some file that's always included - if you have a custom module you're writing for the site, that's a great place to put these functions. The php you enter then is simply: return my_specialfunc($somevar); - $somevar here potentially being the node object worked on, or whatever other variables are relevant here.

I find that I still usually want the flexibility, in some places, of calling my own code. In using this technique, maintaining the code is easy since it's simply a matter of modifying the function in the file. Error-spotting is easy since the function will show up in a backtrace.

Notice, however, that this doesn't solve the potential security issues. These are largely dependent upon the security of the Drupal core. In general, database-contained code is often an achillees' heel of security - functionalities using database-contained code tend to be much more prone to exploitation, and security around them needs to be extra-tight. However, Drupal has in general been quite good at maintaining security for these issues - they have arisen and then quickly patched / solved with new releases.

11

Here is the security vulnerability reason to avoid giving this permission to your users if you don't want your non-admin users to modify the db directly.

<?php
echo file_get_contents(dirname(__FILE__)."/../sites/default/settings.php");
?>

Hacking the Drupal db credentials

7

Rather than doing something like return functionname($object), it would be better to use the tokens/filters system insofar as possible. There are modules like Insert View and Embed Node that can help with common circumstances in which people would want to embed PHP in node or block bodies.

0

You should care about portability of your data. What if you migrate your nodes from drupal 7 to drupal 8 and some node's body text has <?php whatever_function_that_does_not_exist_anymore(); ?> in it?

Do not think about your project within 5 months but within 5 years. Updates, good practices and portability are important aspects of any good IT project in my opinion.

Using as less contributed modules as possible is also one aspect of this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.