Category: PHP

Vulnerable bug in CodeIgniter which took us hours to fix our corrupted database

We use codeigniter internally to develop our web solutions in somewhere in… net limited. Day before yesterday we suffered a terrible situation for an internal bug in code igniter which corrupted data inside some tables of our application database and then it tooks hours to find the origin of that bug, to fix it and to repair the corrupted data. Let me explain what happened.

Lets guess that we have one table named “users” with the following field

1. user_id
2. username
3. password
4. email

At some point, if you want to update the password field of this table, for a particular user, what will you write in your code?


$data = array("password"=>$new_password);
$this->db->where("user_id",$user_id);
$this->db->update("users", $data);

CodeIgniter’s ActiveRecord creates the query like the following

UPDATE users set password='{$new_password}’ where user_id='{$user_id}’;

Well, it’s ok and the quesry seems pretty fine. Now what should happen if you pass a valid user id to this code? Password of only that user will be updated. But what will happen when the passed $user_id is null?? Thats the most pathetic part that Codeigniter ActiveRecord plays. Instead of generating the following query,

UPDATE users set password='{$new_password}’ where user_id=”;

CodeIgniter’s ORM actually generates the following

UPDATE users set password='{$new_password}’ where user_id;

You find the difference of the above two queries right? one contains “where user_id=” ” and another contains just “where user_id” . Now if your backend database is MySQL and this query executes? You know what the hell will happen? It will replace all the user’s password with this new password instead of failing as MySQL count the “where user_id” part equals to false and returns all users. But If your Database is PostgreSQL, it fails, you are lucky.

So day before yesterday we suffered this problem against our commercial application which corrupts our user profile data. We immediate fixed the issue from our backup db (well, we lost 3 data) and then we started to find out what actually went wrong and found this vulnerable bug in CI.

So we suggest the CodeIgniter team to fix the issue immediately and change their ORM code so that it creates the query like the following if the value of passed argument is null. because it will fail to execute in all db. Otherwise the fellow user’s of code igniter, prepare for the dooms day.

UPDATE users set password='{$new_password}’ where user_id=”;

CookieJar in CURL – It Sucks

I was working with Linked in authentication management these days for one of my project where I have to loginto linked in using user’s credentials and fetch personal information and then display it in different form. My code was working properly in local machine, 3 different LAMP servers and one windows server. But finally when I deployed the code in production box, it fails. I quickly found that the cookiejar was not created for some permission problem. I tried to figure out what went wrong but I cant.

1. My script has the permission to create file in that directory on the fly

so there shouldn’t be any problem with this cookie jar and curl, but there was. So hours after hours i spend on it to find the reason and finally I decide to go without cookie jar. And If I don’t use cookie Jar, I have to manually parse the cookies sent to me after login and then set those cookies to my next request so that Linked in recognize me as a “coming back call after login”. I did that and my script worked pretty fine.

Fuck cookie jar in curl. Why the hell the developers didn’t provide a way to override to manage cookies??

If you are interested to know how did I solve it, let me explain a bit.

I set CURLSETOPT_HEADER to true so that I get back the header info
curl_setopt($ch, CURLOPT_HEADER, 1);

and then I parse that header info and extracted the cookies
$end = strpos($header, “Content-Type”);
$start = strpos($header, “Set-Cookie”);
$parts = split(“Set-Cookie: “,substr($header, $start, $end-$start));
$cookies = array();
foreach ($parts as $co)
{
$cd = split(“;”,$co);
if (!empty($cd[0]))
$cookies[] = $cd[0];
}

I will replace this section with RegEx

and finally I set those cookies to my next request using CURLSETOPT_COOKIE
curl_setopt($ch, CURLOPT_COOKIE, implode(“;”,$cookies));

Thats it!! It works pretty fine without cookie jar.

NOTE: I know that cookiejar is a very useful feature for curl users as it automates the cookie management. But I am saying “fuck cookiejar” because developers of curl didn’t provide any way to override cookie management process. If they give us way to use cookijar with any other options beside disk files, it would be beautiful. But in fact I am a big fan of this cookijar feature of curl, except the selfish automation.

WordPress Blogrolls Importer – Opensource

Today I developed this tool to import wordpress blog rolls as XML document. You know when you export data from wordpress.com that doesn’t include the blog rolls data. So if you want to keep a backup of your blog rolls, you can use this tool to import your blog rolls data.. This one is developed using PHP and Curl

importer.gif

You can doewnload it and see the code in action here

Opensource WordPress Blogrolls Importer

################

The trick is lying here —
;

    

    $ch curl_init();

    
curl_setopt($chCURLOPT_COOKIEJAR“./login.jar”);

    

    

    
curl_setopt($chCURLOPT_RETURNTRANSFER,1);

    //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  // this line makes it work under https

    
curl_setopt($chCURLOPT_URL,“{$url}/wp-login.php”);

    curl_setopt($chCURLOPT_POST1);

    
curl_setopt($chCURLOPT_FOLLOWLOCATION,1);

    
curl_setopt($chCURLOPT_POSTFIELDS“log={$username}&pwd={$password}&&redirect_to=wp-admin/link-manager.php&wp_submit=”);

    

    $buffercurl_exec ($ch); // execute the curl command

    

WordPress Plugin for Bengali WordPressians (?)

Ah ya, let me call you WordPressian if you are a wordpress fan. Last night I developed a small plugin for bengali wordpress users. If you install this plugin you will be able to write in Unijoy, Phonetic and Plain English mode. You will get three buttons as shown here
editor.gif

Then you can type Unicode on se,ecting either UniJoy or Phonetic
editor2.gif

And you can write english anytime by clicking English button or pressing Control+C

editor3.gif

Thats it. I will release this plugin under Ekushey.org by Tomorrow

Igniting Code with Code Igniter

Day by day I am loving codeigniter more and more. Its so awesome, rick ellis, you are da man. But unfortunately codeigniter was not properly tested with PostgreSQL. Yesterday I fixed active records insert_id() function to work properly with PostgreSQL. I am running it’s version 8.1

Here comes my modified system/database/driver/postgre/postgre_driver.php

function insert_id()
{
$v = pg_version($this->conn_id);
if (isset($v['server'])) $v = $v['server'];

$table = func_num_args() > 0 ? func_get_arg(0) : null;
$column = func_num_args() > 1 ? func_get_arg(1) : null;

if ($table == null && $v >= '8.1')
{
$sql='SELECT LASTVAL() as ins_id';
}
elseif ($table != null && $column != null && $v >= '8.0')
{
$sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
$query = $this->query($sql);
$row = $query->row();
$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);

}
elseif ($table != null)
{
// seq_name passed in table parameter
$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
}
/**
* another insert id Hack for PostgreSQL
* @author : Hasin Hayder
* @since : March 09, 2007
*/
elseif(is_null($v))
{
$sql='SELECT (LASTVAL()) as ins_id';
}
/**
* End Hack
*/
else
{
return pg_last_oid($this->result_id);
}
$query = $this->query($sql);
$row = $query->row();
return $row->ins_id;
}

Fixing ActiveRecord Class for CodeIgniter to use with PostgreSQL

Hi,

If you are using PostgreSQL and execute the following statement, it will defnitely generate error because of some internal properties in the model.

Controller Code


<?
$model
= $this->load->model("MyModel");
$this->mymodel->insert();
?>

where the model code is


<?
Class MyModel extends Model{
  public $username
;
  
public $password;

  public function insert()
  
{
    $this
->db->insert("table",$this);
  
}
}
?>

So guys – Here I fix the Active Record class in CodeIGniter. Here goes the solution. Just replace the existing insert() function in system\database\DB_active_rec.php

Dont worry, it wont hamper the functionality for other DB providers


/**
     * Insert
     *
     * Compiles an insert string and runs the query
     *
     * @access    public
     * @param    string    the table to retrieve the results from
     * @param    array    an associative array of insert values
     * @return    object
     */
    function insert($table = '', $set = NULL)
    
{
        
if ( ! is_null($set))
        
{
            $this
->set($set);
        
}

        if (count($this->ar_set) == 0)
        
{
            
if ($this->db_debug)
            
{
                
return $this->display_error('db_must_use_set');
            
}
            
return FALSE;
        
}

        if ($table == '')
        
{
            
if ( ! isset($this->ar_from[0]))
            
{
                
if ($this->db_debug)
                
{
                    
return $this->display_error('db_must_set_table');
                
}
                
return FALSE;
            
}

            $table = $this->ar_from[0];
        
}

        /**
         * A small hack for PostgreSQL
         * @author : Hasin Hayder [[email protected]]
         * @since : March 09, 2007
         */
        
if ($this->dbdriver=="postgre"){
            $clone
= $this->ar_set;
            foreach(
$this->ar_set as $key=>$val)
                if (
substr($key,0,1)=="_") unset($clone[$key]);
            
$sql = $this->_insert($this->dbprefix.$table, array_keys($clone), array_values($clone));
        
}
        
else
        
$sql = $this->_insert($this->dbprefix.$table, array_keys($this->ar_set), array_values($this->ar_set));
        
/**
         * End Hack
         */
        
        
$this->_reset_write();
        return
$this->query($sql);
    
}

going for a complete redesign of zephyr

zephyr2.jpg

I am planning for a complete redesign of zephyr, a tiny AJAXed MVC framework for PHP5 developers. So far zephyr has been downloaded 3,975 times from sourceforge and I got several impressive mails from users of zephyr which inspired me a lot. Now it’s time to a complete redesign. Zephyr has been a framework for many of you, but really we can make it more dynamic. Lets make it so easy, so amazing so that a guy who does not know even PHP will be able to use it.

I am planning to make it more “Human” – ha ha ha.

A new look to CodeIgniter, Finally!

CodeIgniter recently gained a lot of attraction from different level of PHP developers because of it’s simplicity and creative flavour. I started learning CakePHP but its so much automated and took time to learn all these stuffs, I moved to CodeIgniter and fall into love with it. Amazing framework.

Recently CodeIgniter website got a new look an feel, a very impressing design indeed. But the sad part of the story is that they also changed the logo which I didn’t like at all. The old logo was much more creative.

Love for CodeIgniter and it’s developers.

Some interesting PHP Apps

While surfing out there, I just find some cool PHP Apps which may come handy for you.

1. Tasks Jr by AlexKing
A task management tool similar to ActiveCollab, BaseCamp and TickSpot

2. MythTv
MythTV is a GPL licensed suite of programs that allow you to build the mythical home media convergence box on your own using Open Source software and operating systems. MythTV is known to work on Linux and Mac OS X (PowerPC and Intel). It does not run on Windows.

3. PHP-Java Bridge
The php/Java bridge is an optimized, XML-based network protocol, which can be used to connect a native script engine, PHP, with a Java or ECMA 335 virtual machine. It is more than 50 times faster than local RPC via SOAP, requires less resources on the web-server side, and it is faster and more reliable than communication via the Java Native Interface.

4. Relay Ajax Directory Manager
An excellent PHP+Ajax directory manager script

5. Vanila
A nice and Simple bulletin board script