PHP: ob_start and header redirect … use it with care


Today, I found a interesting bug in code. This bug has cause our customer to lose data at least 3-4 times in recent past, we read logs and try to find the stories that are causing data loss. But everytime we found no good stories from fact. But today we found the cause of error. Let me explain the problem …

In 5-6 days, we got about 100 records (display per page) from secure admin section of a website. Strangely enough it always delete 100 records (It still remain mystery, why only hundred out of 150 records)..

Why it is happening?

Whenever Alexa craws our website, it delete our records. Now question is why Alexa crawling delete our records. Answer, is we have delete url as http://www.example.com/admin/listing.php?del_id=123. So if you change the 123 with your record id, page will delete that record. However, it has a clause attach, i.e., you need to be logged in system before you do that. Now considering this, how Alexa gain access to password secure area?

Answer to above question: Technical background of page, it use ob_start() as first line of code to execute whenever a secure page is called, then it check the Session if user is logged in or not, if it is not it call the header() function with Location parameter to redirect user to index.php page. Well good enough, if session check if done, it call next line which is not in the ELSE part of Session check. Here it has code that check the $_GET[‘del_id’] and if found delete the record with this id.

Seems fair enough, as in http://www.php.net/ob_start  : “This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers),

So, where is the problem.. well the problem is that when a developer call header function it doesn’t break the execution of page… this result in PHP to send the header before hand, but it also execute the complete page. So, it does the check and doesn’t display the page to client with success message of deletion, and show login form, but it does delete the record from database. Fair enough.

So, some guide to avoid these:

1) Always put code in Else part so if login check successed it execute code.

2) Break you script execution after call to Redirect header, so no further execution take place.

3) Try to cross check delete request, before actually deleting record from database.

4) Put meta header for noindex, and nofollow for admin section.

5) Put robots.txt so NO ONE crawl your website if you don’t want to do so.

Hope that explain the small issue.

,

3 responses to “PHP: ob_start and header redirect … use it with care”

  1. I found your site on technorati and read a few of your other posts. Keep up the good work. I just added your RSS feed to my Google News Reader. Looking forward to reading more from you.

    Jason Rakowski