Firstly, this is not a tutorial on how to write your own Content Management System (CMS).. if I were to write a tutorial on creating a basic CMS it’d be featured on tutorialtastic. This is just a list of things to consider when you decide to embark on the adventure of writing your own CMS.
I cannot emphasise enough how serious it is that you consider security. In fact, don’t just consider security — write it on the back of both hands, your forehead and all over post-it notes stuck to the sides of your monitor/screen. Bookmark as many PHP security sites that you can find, and ask as many knowledgeable people about it that you can.
Security doesn’t just cover you, it covers your users. You have a responsibility to look after data that your users submit to you (name, e-mail address, etc). Look after your data going in to the database by stripping out malicious scripts, HTML tags, PHP and the like. Look after your data coming out of the database by being restrictive about what you display. Other people don’t really need to see anything but a name and a website address (for those people who have one); no e-mail addresses are displayed on my website.
The key to security is to trust nothing. For example, just because you give users a drop-down menu, don’t expect the options in the menu to be the only thing people try and submit. This is demonstrated in the unpatched version of phpFanBase — those with the right know-how are able to submit whatever country they choose through a supposedly restricted menu:
How many people do you know that live in Boobooland?
Data sent through forms isn’t the only thing you need to restrict. The entire set of predifined variables available through the $_SERVER superglobal can be modified/spoofed to suit whatever the malcious user wants.
Lastly, try and keep documents with sensitive information out of the public_html folder. These files can be placed below that level (providing your host allows it). They’re still
include()able, but not accessible via URL. Files and folders which must be public should be protected by as many layers as possible: e.g. use sessions/cookies and .htpasswd protection together.
Be as ‘free’ as you can when designing your database structure. While in depth knowledge of normalised databases, primary keys, etc. are always handy, all you really need is a bit of common sense. It’s redundant having a pages table with only a name and content field — go ‘big’ and add an id field (which will be unique to each entry — the primary key) a category field, perhaps a description for archiving purposes, a comments on/off field, will you want that page private or public? Don’t forget date, too.
Your tables need to be joined in some way. There’s no point having a pages table and a comments table if there’s no way to distinguish which posts go with which comments and so on. Each comment should have a unique id (the primary key for the comments table), a page-id to match the pages table (the foreign key), and then you’ll want to think about name, e-mail address, etc. If you’re into monitoring statistics on your visitors, don’t forget to log their IPs, and the browser they’re using (but remember these items are all spoofable!)
Be sure to do your planning up front. Don’t do a quick database set up and code your entire CMS only to go and realise that you need to re-code the entire lot because you’ve changed your database structure.
Don’t stick to generic naming conventions when it comes to folders and files you want to keep secure. The first thing a malicious user is going to look for is a config file of some sort. Name this something like like IEATPIE.php. Likewise, folders needn’t be called /admin/ or /controlpanel/; instead name them something like /breasts/ or /mytoothpasteisgreen/.
The same could be said for header and footer includes. Although generally no sensitive information is found in these files, you may be using them to include files which do contain information that you want protecting. A slight change — e.g. to head.php instead of header.php — can make a difference.
Dealing with Spam
Spam affects most of us. In fact even my own weblog, which was so delightfully spam-free for so many months after I originally wrote the script, now gets spammed a couple of times a day. There are new methods I’ve learnt that I could implement to deal with it, but generally it’s easier for me to just delete it. Don’t let it get to you though.
Don’t just try to protect against comment spam either — you need to make sure that people can’t send e-mails through your forms to thousands of people. I have found that checking data input against an array of common words used in mail-sending (like content-type, bcc and cc) and delivering an error if they’re found is the best way to combat this (and has been 100% successful on my contact forms).
Once you’ve coded your CMS and got your database structure online there are many things you’ll need to consider. Will you want an RSS Feed? How will you display your comments? Will you want to implement pinging with XML-RPC to save you from having to ping Technorati and the like manually?
Bear in mind that so many features in your average CMS/weblog system are invisible to you until you are without them. WordPress for example, handles pings and trackbacks, comment spam, appropriate data logging, a proper admin panel, etc. for you. Don’t take this for granted, and remember that coding a fully functional and secure system can be harder than it looks, even if it is ultimately worth it in bragging rights at the end.
And don’t forget that security!
(As featured on Dead-Teddybears.com)