Debugging For Dummies
It’s the typical scenario. 1am, lots of coffee, little sunlight. You’re working on the next great idea. An application that you’re quite excited about.
You set up a simple token to secure it against csrf:
$transact_token = md5( uniqid(rand(), true) );
$this->session->set_userdata('act_tok', $transact_token);
You add a hidden field to your form.
And after the submission compare it:
$req = $this->input->post('act_tok');
$cookie = $this->session->userdata('act_tok');
if ($req != $cookie)
{
die('hacking attempt');
}
All pretty basic. And then it hits. The bug of all bugs.
Obscurity
It almost never matches. Occasionally though, it does. As if by some evil trick.
So you start to debug. Add echo and die statements everywhere. Change random, seemingly unrelated code. Turn off javascript.
As you run out of ideas, you open up the session library and run a few queries.
$this->CI->output->append_output($this->CI->db->last_query().'<br />');
// It updated, now grab it
$q = $this->CI->db->get('ci_sessions');
$q = $q->row_array();
$this->output->append_output($q['user_data'].'<br />');
Refresh the browser…
09ae062f792313f1abf5069aaca34a5f
09ae062f792313f1abf5069aaca34a5f
Wohoo, it works?
Back to mysql.
mysql> SELECT * FROM (`sessions`);
user_data
8b2109106e87a0fe28d31a5b0b5fad47
1 row in set (0.00 sec)
The devil is at work here.
Ok, don’t give up yet - what else?
How can you find this…
... how ...
Server Logs
localhost - - [06/Oct/2008 01:05:56] "GET /favicon.ico HTTP/1.1" 200 -
...
$route['.*'] = 'home';
Comments
#1 | Posted on October 6th, 2008 Pascal said:
Sorry for being so shambolic. Took me two hours to find the bug. I’m done for today…
#2 | Posted on October 6th, 2008 aroman said:
im confused, i couldnt find a bug in your code above.
could you tell us how did u find the bug ?
-aroman
#3 | Posted on October 6th, 2008 Pascal said:
Hehe, I can’t say I wasn’t expecting it.
Modern browsers always make a request to the favicon. The application in question didn’t have a favicon, instead the request went to a regular controller.
All of my controllers set the csrf token (MY_Controller). So when I ran a request, I got the proper hidden field. But the browser also sent a request to the favicon, which altered the token in the database.
So they would almost never match. Unless I was at the homepage (something I didn’t catch on to).
It all comes down to the catch-all route (and a bad .htaccess).