Say you put together a nice, static site for a client. There’s a lot of CSS, a fair amount of scripting (in whatever language – we’ll assume PHP here), a handful of images, and a lot of HTML. The client is going to manage the site with a WYSIWYG editor.
What’s the biggest danger to your site? The person you hand it over to, of course. Invariably, they’ll get into files they shouldn’t, delete images they shouldn’t, or embark on CSS “upgrades” that they shouldn’t.
Shortly thereafter, you’ll get a call that begins, “The site doesn’t look right...”
How do you prevent this? Well, with a lot of hosts, you can finagle a few ways to prevent them from messing with things they shouldn’t by using additional FTP users and some Apache directives.
Many *nix-based Web hosting companies will allow you to set up additional FTP users with their own FTP directories. I’m going to use Plesk in this example, because that’s the platform we use at Gadgetopia. Other systems have similar ends, but the file paths will be different.
Consider this structure for a virtual host:
“/” is the root of the Apache virtual host. The master FTP account logs into this directory. There’s a lot of things in here that you don’t want messed with: the virtual host configuration files in “conf,” and the Perl scripts in “cgi-bin,” to name but two.
With Plesk, when you create a new FTP user, they get a directory in “web_users.” In this instance, we’ve created “editor.” This user’s files would be accessible with a URL of “www.site.com/~editor/” The “editor” directory, then, is their own virtual root.
Let’s say that our site has 10 HTML pages. When you’re done developing everything, put these pages in the “web_users/editor” directory instead of the virtual root and give your editor FTP credentials to that directory only.
Then, in the configuration file for the virtual root, add some lines like this:
Alias ^/about_us.html$ [...]/web_users/editor/about_us.html
(“[...]” would be replaced with the path to the Apache virtual root, be it “/home/httpd/vhosts/domain_name” as with Plesk or whatever.)
This means, when a visitor requests the “About Us” page, Apache pulls it from the “editor” directory – to which the user has all rights.
(Yes, this page can also be accessed like this:
If that stresses you out, this directive...
AliasMatch ^~editor/.*$ /doesnt_exist.html
...will send direct request to the editor directory spinning off into 404 land. An ugly, but effective, solution.)
To manage the HTML content, the editor will FTP into the “editors” directory (they’ll be deposited there when they use their credentials) and see only the HTML files in there. The “editor” directory will be the “top” directory the editor can get to. The editor won’t see any of the PHP files you use to make the site run, nor will he or she be able to get into the cgi-bin, the configuration directory, the SSL source directory, etc.
If you just have a handful of pages, you can enter an Alias rule for each one. If you have a lot, or if the user can create more on his or her own, have a rule like this:
AliasMatch ^/([^.]).html$ [...]/web_users/editor/$1.html
This will take a request for...
...and pull it from...
You could do it using rewrites as well:
RewriteRule /([^.]).html /~editor/$1.html
If you want to give the editor the ability to create subfolders and such, it gets a little more difficult, but not much. Just figure out what folders you have in the (actual) root of the site, and send anything else to the “editor” directory.
For instance, say you have a folder called “static_images,” “php_bin,” and a stylesheet in the actual root of the site. This rule...
RewriteRule ^/([^static_images|php_bin|style.css].*)$ /~editor/$1
Will use the “editor” directory for any request not bound for those two directories or the stylesheet. (This is how I did it, but it occurs to me that there’s probably a much better way. I just stuck with the first thing that worked. If you know of a better method, please comment.)
Finally, if you have a script-happy editor, and you need to prevent them from writing any PHP, try this:
<directory [...]=”” web_user=”” editor=””>
php_admin_value php_engine off
This will kill the PHP engine for anything coming out of their directory. Be prepared for them to be mighty irritated.
Example: there is a way to configure mod_rewrite to check two roots for a file. If it doesn’t find a file in the actual Web root, it will check the alternate Web root (the editor’s directory). Thus, you, as the developer, have “first rights” to any URL (“/search.php” for instance).
Your editor can have any URLs that you haven’t used. They can create “search.php” pages in their root all day long, but any request to “/search.php” will still pull from the page in the actual Web root, that only you have access to. (Yes, they can just change where the search form points, but this is a much more delibrate – and incriminating – action.)
To be sure, editors can still screw themselves. But you’ve sealed off some of the more obvious ways, and eliminated that many more headaches from your job.