Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

If you are using a verson prior to 5.3.6, this will be ignored.
Instead, you must run $dbh->exec("set names latin1");
Source: http://stackoverflow.com/a/4361485https://stackoverflow.com/a/4361485
Luckly, PHP has a function to solve this kind of issue: version_compare().
The version can be checked like this: version_compare(PHP_VERSION, '5.3.6', '<')
Documentation: http://php.net/manual/en/function.version-compare.php

If you are using a verson prior to 5.3.6, this will be ignored.
Instead, you must run $dbh->exec("set names latin1");
Source: http://stackoverflow.com/a/4361485
Luckly, PHP has a function to solve this kind of issue: version_compare().
The version can be checked like this: version_compare(PHP_VERSION, '5.3.6', '<')
Documentation: http://php.net/manual/en/function.version-compare.php

If you are using a verson prior to 5.3.6, this will be ignored.
Instead, you must run $dbh->exec("set names latin1");
Source: https://stackoverflow.com/a/4361485
Luckly, PHP has a function to solve this kind of issue: version_compare().
The version can be checked like this: version_compare(PHP_VERSION, '5.3.6', '<')
Documentation: http://php.net/manual/en/function.version-compare.php

Added security correction, according to the comment made by @EliasVanOotegem
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62

In terms of security, I have nothing else to say.
YouYou can use the mcrypt list of function.
For documentation, you can check here: http://php.net/manual/en/ref.mcrypt.php

Edit:

As @EliasVanOotegem pointed out on his comment, the collation isn't being set.
Appending ';charset=latin1' to the string should do it.

If you are using a verson prior to 5.3.6, this will be ignored.
Instead, you must run $dbh->exec("set names latin1");
Source: http://stackoverflow.com/a/4361485
Luckly, PHP has a function to solve this kind of issue: version_compare().
The version can be checked like this: version_compare(PHP_VERSION, '5.3.6', '<')
Documentation: http://php.net/manual/en/function.version-compare.php

Now, you may ask: why not utf8?
The reason is that the default collation for most servers is in fact latin1_swedish_ci.
This means that a password like aç$%dKeä would be returned as scrambled data.
When you try to connect to the other database, using mysqli_*, the connection would be always rejected because the password would be different.

    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }

This is not a realreal issue, but you are concatenating an empty string on the PDO initialization.
Here is the code:

The final code (security apart, reflecting the edit):

<?php

    include('.dbinc.cred.inc.php');

    try {
    
        $dbh = new PDO('mysql:host=' . HOST_ONE . ';dbname=' . DB_ONE . ';charset=latin1', USER_ONE, PASS_ONE);
        
        if(version_compare(PHP_VERSION, '5.3.6', '<'))
        {
            $dbh->exec('set names latin1');
        }
        
        $statement = $dbh->prepare('SELECT user_db, user_db_pass, user_db_user, user_name FROM databases WHERE user_name = :name');
        $statement->execute(array('name' => $_SESSION['user_name']));

        list($user_db, $user_db_user, $user_db_pass) = $statement->fetch(PDO::FETCH_NUM);
        
        $statement->closeCursor();
        
        unset($statement, $dbh);

    }
    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }
    
    $sql = new mysqli(HOST_ONE,$user_db_user, $user_db_pass,$user_db);
    $sql -> set_charset('utf8');
    if ($sql->connect_errno)
    {
        echo '<script type="text/javascript">location.href="#ajax/account_setup.php";</script>';
    }

?>

As a micro-optimization, I swapped the quotes.
In terms of real-world usage, using "" would make a negligible difference.
Use the quotes that you prefer, I simply prefer to save some CPU cycles.

Thanks to @EliasVanOotegem for spotting the safety issue regarding the lack of a specification on the used collation to connect to the database.
This is a serious issue because it changes the way that the parameters are escaped and avoids the use of special characters to 'nullify' the escapes, allowing other commands to run.
You can see how this attack is performed in here: http://hakipedia.com/index.php/SQL_Injection#Filter_Bypassing

In terms of security, I have nothing else to say.
You can use the mcrypt list of function.
For documentation, you can check here: http://php.net/manual/en/ref.mcrypt.php

    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }

This is not a real issue, but you are concatenating an empty string on the PDO initialization.
Here is the code:

The final code (security apart):

<?php

    include('.dbinc.cred.inc.php');

    try {
    
        $dbh = new PDO('mysql:host=' . HOST_ONE . ';dbname=' . DB_ONE , USER_ONE, PASS_ONE);

        $statement = $dbh->prepare('SELECT user_db, user_db_pass, user_db_user, user_name FROM databases WHERE user_name = :name');
        $statement->execute(array('name' => $_SESSION['user_name']));

        list($user_db, $user_db_user, $user_db_pass) = $statement->fetch(PDO::FETCH_NUM);
        
        $statement->closeCursor();
        
        unset($statement, $dbh);

    }
    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }
    
    $sql = new mysqli(HOST_ONE,$user_db_user, $user_db_pass,$user_db);
    $sql -> set_charset('utf8');
    if ($sql->connect_errno)
    {
        echo '<script type="text/javascript">location.href="#ajax/account_setup.php";</script>';
    }

?>

As a micro-optimization, I swapped the quotes.
In terms of real-world usage, using "" would make a negligible difference.
Use the quotes that you prefer, I simply prefer to save some CPU cycles.

You can use the mcrypt list of function.
For documentation, you can check here: http://php.net/manual/en/ref.mcrypt.php

Edit:

As @EliasVanOotegem pointed out on his comment, the collation isn't being set.
Appending ';charset=latin1' to the string should do it.

If you are using a verson prior to 5.3.6, this will be ignored.
Instead, you must run $dbh->exec("set names latin1");
Source: http://stackoverflow.com/a/4361485
Luckly, PHP has a function to solve this kind of issue: version_compare().
The version can be checked like this: version_compare(PHP_VERSION, '5.3.6', '<')
Documentation: http://php.net/manual/en/function.version-compare.php

Now, you may ask: why not utf8?
The reason is that the default collation for most servers is in fact latin1_swedish_ci.
This means that a password like aç$%dKeä would be returned as scrambled data.
When you try to connect to the other database, using mysqli_*, the connection would be always rejected because the password would be different.

catch (PDOException $e){
    die('Error!: ' . $e->getMessage() . '<br/>');
}

This is not a real issue, but you are concatenating an empty string on the PDO initialization.
Here is the code:

The final code (security apart, reflecting the edit):

<?php

    include('.dbinc.cred.inc.php');

    try {
    
        $dbh = new PDO('mysql:host=' . HOST_ONE . ';dbname=' . DB_ONE . ';charset=latin1', USER_ONE, PASS_ONE);
        
        if(version_compare(PHP_VERSION, '5.3.6', '<'))
        {
            $dbh->exec('set names latin1');
        }
        
        $statement = $dbh->prepare('SELECT user_db, user_db_pass, user_db_user, user_name FROM databases WHERE user_name = :name');
        $statement->execute(array('name' => $_SESSION['user_name']));

        list($user_db, $user_db_user, $user_db_pass) = $statement->fetch(PDO::FETCH_NUM);
        
        $statement->closeCursor();
        
        unset($statement, $dbh);

    }
    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }
    
    $sql = new mysqli(HOST_ONE,$user_db_user, $user_db_pass,$user_db);
    $sql -> set_charset('utf8');
    if ($sql->connect_errno)
    {
        echo '<script type="text/javascript">location.href="#ajax/account_setup.php";</script>';
    }

?>

As a micro-optimization, I swapped the quotes.
In terms of real-world usage, using "" would make a negligible difference.
Use the quotes that you prefer, I simply prefer to save some CPU cycles.

Thanks to @EliasVanOotegem for spotting the safety issue regarding the lack of a specification on the used collation to connect to the database.
This is a serious issue because it changes the way that the parameters are escaped and avoids the use of special characters to 'nullify' the escapes, allowing other commands to run.
You can see how this attack is performed in here: http://hakipedia.com/index.php/SQL_Injection#Filter_Bypassing

Added a new correction to the tag <script> on the last echo
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62

Almost at the end of the code, you have this echo:

echo "<script language=JavaScript>location.href='#ajax/account_setup.php';</script> ";

The language attribute is deprecated and can be safely dropped. (Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-language )
This was useful in the times when VBScript was used for Internet Explorer, to diferentiate both languages.
Nowadays, you don't need this.
Another thing is that the value of the attribute isn't between quotes.
If you are paranoid about this, you can use the type attribute.
You can set the value text/javascript, being the final code like this:

echo '<script type="text/javascript">location.href="#ajax/account_setup.php";</script>';

Documentation about the type attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type

<?php

    include('.dbinc.cred.inc.php');

    try {
    
        $dbh = new PDO('mysql:host=' . HOST_ONE . ';dbname=' . DB_ONE , USER_ONE, PASS_ONE);

        $statement = $dbh->prepare('SELECT user_db, user_db_pass, user_db_user, user_name FROM databases WHERE user_name = :name');
        $statement->execute(array('name' => $_SESSION['user_name']));

        list($user_db, $user_db_user, $user_db_pass) = $statement->fetch(PDO::FETCH_NUM);
        
        $statement->closeCursor();
        
        unset($statement, $dbh);

    }
    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }
    
    $sql = new mysqli(HOST_ONE,$user_db_user, $user_db_pass,$user_db);
    $sql -> set_charset('utf8');
    if ($sql->connect_errno)
    {
        echo '<script language=JavaScript>locationtype="text/javascript">location.href="#ajax/account_setup.php";</script> ';script>';
    }

?>
<?php

    include('.dbinc.cred.inc.php');

    try {
    
        $dbh = new PDO('mysql:host=' . HOST_ONE . ';dbname=' . DB_ONE , USER_ONE, PASS_ONE);

        $statement = $dbh->prepare('SELECT user_db, user_db_pass, user_db_user, user_name FROM databases WHERE user_name = :name');
        $statement->execute(array('name' => $_SESSION['user_name']));

        list($user_db, $user_db_user, $user_db_pass) = $statement->fetch(PDO::FETCH_NUM);
        
        $statement->closeCursor();
        
        unset($statement, $dbh);

    }
    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }
    
    $sql = new mysqli(HOST_ONE,$user_db_user, $user_db_pass,$user_db);
    $sql -> set_charset('utf8');
    if ($sql->connect_errno)
    {
        echo '<script language=JavaScript>location.href="#ajax/account_setup.php";</script> ';
    }

?>

Almost at the end of the code, you have this echo:

echo "<script language=JavaScript>location.href='#ajax/account_setup.php';</script> ";

The language attribute is deprecated and can be safely dropped. (Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-language )
This was useful in the times when VBScript was used for Internet Explorer, to diferentiate both languages.
Nowadays, you don't need this.
Another thing is that the value of the attribute isn't between quotes.
If you are paranoid about this, you can use the type attribute.
You can set the value text/javascript, being the final code like this:

echo '<script type="text/javascript">location.href="#ajax/account_setup.php";</script>';

Documentation about the type attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type

<?php

    include('.dbinc.cred.inc.php');

    try {
    
        $dbh = new PDO('mysql:host=' . HOST_ONE . ';dbname=' . DB_ONE , USER_ONE, PASS_ONE);

        $statement = $dbh->prepare('SELECT user_db, user_db_pass, user_db_user, user_name FROM databases WHERE user_name = :name');
        $statement->execute(array('name' => $_SESSION['user_name']));

        list($user_db, $user_db_user, $user_db_pass) = $statement->fetch(PDO::FETCH_NUM);
        
        $statement->closeCursor();
        
        unset($statement, $dbh);

    }
    catch (PDOException $e){
        die('Error!: ' . $e->getMessage() . '<br/>');
    }
    
    $sql = new mysqli(HOST_ONE,$user_db_user, $user_db_pass,$user_db);
    $sql -> set_charset('utf8');
    if ($sql->connect_errno)
    {
        echo '<script type="text/javascript">location.href="#ajax/account_setup.php";</script>';
    }

?>
Added the documentation for the PDOStatement::closeCursor() function.
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62
Loading
Source Link
Ismael Miguel
  • 6.1k
  • 2
  • 23
  • 62
Loading