Make WordPress Core

Opened 10 years ago

Closed 10 years ago

#28105 closed enhancement (wontfix)

Feature (with patch): allow system-wide inclusion of code

Reported by: davidanderson's profile DavidAnderson Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.0
Component: Plugins Keywords: close
Focuses: Cc:

Description

A way for a server operator to be able to include code, in a plugin-like fashion, on every site on his server would be very useful.

Example use cases:

  • Collating system-wide IP data from distributed attacks (and feeding that data to a firewall)
  • Detect and terminate brute-force attacks early (e.g. detect certain $_POST patterns, and end execution before further server resources are used)
  • Require a local plugin on every site, without needing to manage every site individually (e.g. hosting-company-provided automatic backups)
  • Have a default hook into wp_mail() that uses the local SMTP setup
  • Hook into a local cacheing system

From that list of 5 examples, you can see that the potential is infinite. Currently, system administrators would have to install and activate a plugin on every WordPress site; or alternatively use PHP's auto_append_file configuration variable.

The attached patch enables this functionality. It provides a defined file location that a system administrator can place his PHP code at, to hook into WordPress. It runs immediately before mu-plugins, and hence unlocks all the potential of an mu-plugin.

Possible questions:

Objection: It's creepy! We don't want system administrators to be able to include code on my site.
Answer: They already can, via PHP's auto_append_file. Or, since they're the system administrator, they could just auto-modify your WordPress core. The options are infinite. If you have reasons to distrust your sysadmin, then this patch changes absolutely nothing for you.

Objection: If the sysadmin introduces a PHP error in the included file, then he'll cause every site on the server to fall over!
Answer: Of course. Same as if he mis-configures the webserver or pours juice over the hardware. Sysadmins have the power to break everything if they lack proper sysadmin skills. Again, if your sysadmin is this kind of person, then this patch makes no difference.

Question: Why isn't the inclusion path over-ridable via a constant?
Answer: Because it's not intended to be site-local configuration. It's intended to be a server-wide setting. If the sysadmin wants a particular site to be opted-out, then he should add code for that in the system-wide included file.

Question: If server admins can already do this via installing plugins or auto_append, then why is that not sufficient?
Answer: Installing an mu-plugin on each site, for example, has a lot of over-head: it needs to be done on every site, and there'd need to be a mechanism for detecting new sites when they appear. auto_append also severely limits what bits of WordPress can be hooked into, as it's running too late. auto_prepend could be used, together with pluggable functions, but it involves ugly hacks. The solution in the patch makes what is already possible to be both possible and elegant.

Attachments (1)

syswide.diff (2.1 KB) - added by DavidAnderson 10 years ago.
Include system-wide configuration file

Download all attachments as: .zip

Change History (12)

@DavidAnderson
10 years ago

Include system-wide configuration file

#1 follow-up: @juliobox
10 years ago

hello

you already can do this using mu-plugins or symlink plugings, i don't think this is relevant to add this.

my 2 cents

#2 in reply to: ↑ 1 @DavidAnderson
10 years ago

juliobox: that was addressed in the original post. Someone who's got 500 WordPress websites on a single server, with sites coming and going at different times day by day, would have to devise tools to create and monitor symlinks in real-time to make that work. That would be ugly and unreliable.

#3 @DavidAnderson
10 years ago

juliobox: I forgot to add: the location of the mu-plugins directory is also a site-configurable setting. This doesn't help server administrators who want to hook into sites without first having to analyse their local configuration.

#4 @Denis-de-Bernardy
10 years ago

  • Keywords close added

@David: there is no need to do any of that. Just add a WPMU_PLUGIN_DIR define in each wp-config.php file -- or for that matter, using a php prepend directive.

Suggesting invalid.

Last edited 10 years ago by Denis-de-Bernardy (previous) (diff)

#5 follow-up: @DavidAnderson
10 years ago

Denis: I dealt with that suggestion in the rationale given in the original text. 1) Such a solution involves setting up a custom solution for monitoring the appearance and disappearance of WordPress installs on the server 2) WPMU_PLUGIN_DIR is site-level configuration, whereas the ticket is about providing a solution for server/system-level configuration.

WordPress is increasingly being approached from a systems administration angle, as well as a webmaster angle. System administrators have been designing 1-click installers, and looking at how they resolve problems like brute-force attacks against multiple sites at once, auto-modifying robots.txt (e.g. Crawl-delay), and the like (examples in the original text). Presently, WP makes this dificult. The other solutions so far suggested are very cumbersome. My simple patch makes it easy.

Last edited 10 years ago by DavidAnderson (previous) (diff)

#6 in reply to: ↑ 5 @Denis-de-Bernardy
10 years ago

Replying to DavidAnderson:

Denis: I dealt with that suggestion in the rationale given in the original text. 1) Such a solution involves setting up a custom solution for monitoring the appearance and disappearance of WordPress installs on the server

Or not… Edit the PHP settings, add an auto_prepend_file directive. The file's contents:

<?php define('WPMU_PLUGIN_DIR', '/path/to/folder');

Other PHP apps will get a new define they won't care about, and all WP installs will use your mu-plugins.

Last edited 10 years ago by Denis-de-Bernardy (previous) (diff)

#7 @DavidAnderson
10 years ago

Denis: I don't think you're getting my point about site-level versus system-level configuration. Your solution means that the site's configuration for WPMU_PLUGIN_DIR is over-ridden.

The kind of example I'm looking at is this: a) the site-builder has built his site, which may have any kind of mix of themes, plugins and mu-plugins. b) the system administrator also wishes to add in some compulsory code, e.g. to enforce auto-backups, to enforce a minimum Crawl-Delay in robots.txt, to log failed login attempts across all sites, in order to feed the data to an IPS/firewall.

If the system administrator force-overrides WPMU_PLUGIN_DIR, then that action will interfere with any mu-plugins that the site-builder had. It would enforce a convention that mu-plugins are for the system admin, and not available to the site-builder. That's not workable in the general case (e.g. the system admin might be a web hosting company and have no other relationship with the site builder). I am looking for a solution that allows the system administrator to use hooks and filters in a way that will be minimally surprising/intrusive for the site builder.

#8 @Denis-de-Bernardy
10 years ago

Which sounds fair enough, but I then beg to ask why WordPress should accommodate this any more than other pieces of Software? Did you open the same ticket with e.g. Drupal, Joomla, OSCommerce, phpBB, CMF, any one of the other gazillions of PHP software out there in the wild, or for that matter any of the plethora of PHP frameworks out there?

Come to think of it, that probably is the main problem I see with this feature request. It's not a particularly bad idea per say. I think it even has some merit.

But then: Why WordPress in particular? Especially when you consider the fact that you *can* do this already by overriding a define to achieve this using an auto_prepend_file directive?

If defining the WPMU_PLUGIN_DIR folder is not good enough, you could achieve the same using:

<?php
foreach (glob("/path/to/folder/*.php") as $file) {
  require $file;
}
unset($file);

As a bonus, the same scripts will work for all PHP applications.

Which brings me to: Why would WordPress need to have a set of functionality that is any different from other PHP apps (or Ruby, Python, or [favorite language goes here] app, for that matter) in order to enforce auto-backups (which can and probably should be done by a cron that dumps mysql directly) or enforce a minimum Crawl-Delay in robots.txt (which can and probably should be done using e.g. an Apache module before traffic even hits the PHP scripts)?

The idea of logging failed login attempts to feed a firewall admittedly rings truer since it's not taken care of in WP Core yet, but then you can monitor hits on the wp-login.php file (using an auto_prepend_file directive for instance) to do the same, and enforce any number of actions before the traffic ever hits the WordPress installation.

On a related note, I can think of plenty of reasons for wanting add_filter() and add_action() for a few of these WP-specific sysadmin tasks. But I'm afraid this was rejected in #27208 when I suggested it a few weeks ago.

In the end, I'm not saying the current situation is a panacea. Just that, you know… Why should WordPress be held to different standards from other applications, and expose a particular API for the convenience of hosting companies? Why should we not politely tell them that they've plenty of tried and tested solutions already which, as a bonus, also work with other applications?

#9 @Denis-de-Bernardy
10 years ago

Aside — A completely unintrusive approach using auto_prepend_file and WP API is this:

<?php
$wp_filter['muplugins_loaded'][~PHP_INT_MAX]['server_wide_loader'] = array(
    'function' => 'server_wide_loader',
    'accepted_args' => 0,
);

function server_wide_loader() {
    # do stuff
}

#10 @DavidAnderson
10 years ago

Hi Denis,

That method with $wp_filter seems to give me what I'm looking for - thank you.

I can't speak for others, but for myself, being able to register specifically WP actions and filters is interesting because WordPress is covering the majority of sites that people want to put onto shared hosting currently. It's WordPress that the bad guys are hammering with their brute force attacks, etc. And, of course, code that hooks into WP's filters for failed logins, or robots.txt, etc., isn't going to run in another CMS, as far as I can see - i.e. PHP that deals with an IP address of a failed login (or 100 failed logins, etc.) isn't going to be portable across different PHP applications without modification for each application. (Obviously it's portable once you've got the data that "this is a failed login", but that's the interesting bit - and as I say, it's WP that the automated attacks are against these days, because of market share. Targetting even number 2 (is that Joomla?) isn't anything like as economic for them).

Anyway - so, that unofficial method works. That's good enough for me to use. I'd still be in favour of an official method, but I'm happy to stop advocating for it now and to leave it to others, as I've given my view.

#11 @helen
10 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Agree that this doesn't seem like core territory.

Note: See TracTickets for help on using tickets.