Writing Your Own CMS

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.

Security

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:

boobooland?

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.

Structure

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.

Naming Files/Folders

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.

Before embarking on coding your commenting system, do research on how other people combat spam. My bad word system gets rid of 90% of mine, but there are other solutions. Captchas, timed sessions and the hidden JavaScript field method that I’ve just introduced to BellaBook, inspired by Bubs.

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).

Finishing Touches

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)

14 Comments

  1. Do many people write their own CMS? I think it would be cool to do that so I could have it exactly the way I want, but that will probably be many years in the future. ;)

  2. Thanks for this entry! Security is an important issue. My programming skills are far away from beeing able to write a cms, but I am really curious to know how CMS are created.

  3. Yes, yes, yes on the security bit! (Your other advice is good to, of course.) So many people don’t understand about SQL injection, XSS, etc. or don’t know how to protect against them. And (this is just a huge pet peeve of mine) use strong passwords, please! ‘apple1’ will not cut it. Case-sensitive, with special characters and numbers — the more character types, the longer it takes to brute force. Really, it’s always best to be on the safe side and overdo the security (if that’s possible). You have to assume that every user is malicious or dangerously ignorant/curious and plan for as many unintended situations as possible. What happens if they manually change your dynamic URLs? Or stick weird (perhaps SQL-injecting or javascript) characters in the search form? Mail header injection is pretty serious as well, and insecure mail scripts could get your hosting account suspended/cancelled. It’s not just your contact form you need to worry about, either. What about your comment processing? If it sends an email to notify you of new comments, the same dirty spammer tricks can and will be tried there (most of the header-injection attempts I get are actually in my blog comments). Online app security is quite serious, but so many people just don’t take the time for it. And there’s not really any good excuse for that, because so many of the good security practices are really pretty easy to understand and implement.

  4. Amen. That is all. :P

  5. I wish I would be able to write my own CMS. However, I have no formal training in PHP or anything fancy like that and I’m not even in high school. However, wonderful article, and I will refer to it in the future. :)

  6. *bows in the awesomness of Jem* THANKYOUTHANKYOUTHANKYOU! Totally needed this, it’s a nice fire under my ass to get FCMS done already… Great article! :D

  7. i work in developing content managed systems and found your article very interesting, good job :)

  8. I never thought of the second part of the guide… naming your files randomly… That’s a really smart idea!

  9. I’m from brazil, RSS FEED form Latest Tutorials brought me here…. I didn’t read the whole article… but i saw that finally I found something that i’m searching for a long time… people who know much about CMS. []’s

  10. Ralph Hardwick

    31 Aug at 9:43 am

    I have been a web developer for 10 years, most of those years spent developing CMS packages of all sizes. I have written TCL code for a vast Vignette Story server based system as well as tens of bespoke systems that have been created from scratch to fit a clients needs. The point is that for the level this article is aimed at I can’t think of anything else I would add.

  11. Old Post, but what the hey. Thanks so much for this Jem, I’m embarking on a write-my-own CMS project and I will need all the help I can get, I’ve bookmarked this for future reference! :P

  12. Hi, great article! Its always worth re-reading these sort of security articles when your programming. Can someone explain further on how to combat submitting whatever value a user wants from a drop down? I was a bit surprised by this as I thought drop downs were the most secure form field available :) ” right know-how are able to submit whatever country they choose through a supposedly restricted menu” . Thanks

  13. Jem

    08 Oct at 3:55 pm

    Hi Chris. I replied with full examples via email, but the quick answer is to use arrays to populate and validate drop-down input.

  14. good tutorilal. I am currently writing a CMS and finding security the hardest part!