Blog

There seems to be a bug in Thin that keeps erroring out when you try to run “thin start.” It would complain that the Rails 2.3.5 gem is not installed even though it shows up on a “gem list” command. It seems like the problem has something to do with the way Thin handles Rack. If you “gem uninstall -v”, all the newer versions and keep Rack 1.0.1 it seems to run perfectly fine.

I hope this helps anybody that else that uses Thin.

silverpop_core

Our team at ShoeDazzle.com has just switched our emailing providers to Silverpop. Unfortunately, there weren’t any existing Ruby projects that integrated with Silverpop’s XML API. After several weeks of development, I have finished a simple, but working framework to generate the XML code for Silverpop’s Engage and Transact service. XML code can be submitted through a HTTP/HTTPS post service or through FTP uploads.

In the spirit of open source and with permission from my awesome manager, I am releasing the code under the MIT license for other developers that are looking to integrate their Rails project with Silverpop. You can clone a copy from http://github.com/georgetruong/silverpop

Good luck and hope this helps.

I was just reading this article the other day about how 4chan hackers compromised a Christian singles dating site. They went on to use the emails / passwords gathered to launch an attack on these users Facebook accounts. On Facebook, they posted a lot of not safe for work pictures and wrote many profane status updates.

This got me thinking about a lot of projects where I had to correct and secure web applications that store plain text passwords. Perhaps I’m just paranoid, but it baffles me how many projects out there maintain this process.

Hopefully, this script can be useful to those who are looking to improve the security of their authentication system.

The Code


<?php

function generate_salt($email) {
    // Create a SHA1 hash
    $salt = sha1('~'.$email.'~'.microtime(TRUE).'~');

    // Limit to random 10 characters in the hash
    $salt = substr($salt, rand(0,30), 10);

    return $salt;
}

function hash_password($password, $salt) {
    return sha1('~'.$password.'~'.$salt.'~');
}

function valid_password($password, $hash, $salt) {
    return hash_password($password, $salt) == $hash;
}

//  CREATING A USER:
echo "*** CREATE USER ***\n";

//  -> This data would be gathered from a signup form
$form_email = 'bill@test.com';
$form_pass  = 'password';

//  -> We would have to generate a password hash and salt for them
echo 'SALT = '.generate_salt($form_email)."\n";
echo 'HASH = '.hash_password($password, $salt)."\n";
echo "\n";

//  CHECKING CREDENTIALS:
echo "*** LOG USER IN ***\n";

//  -> This data would be from the login form
$form_email = 'jack@test.com';
$form_pass  = 'secret';

// -> This data would be gathered from the user's database record
$db_hash    = '99079df72d0cc065ebde85da906a544b5078cf7d';
$db_salt    = 'a1ef1118b2';

if (valid_password($form_pass, $db_hash, $db_salt))
    echo "LOGGED IN\n";
else
    echo "NOT LOGGED IN\n";

Explanation

Instead of saving passwords in straight text, we will be generating a random salt string and use it to obscure the password being saved into the database.

The generate_salt() function takes the user’s email address, adds the current UNIX timestamp, and creates a 40 character SHA1 hash. To further obscure the salt, I randomly select at 10 character string within the hash to be the salt.

Once we have a salt string, we can call hash_password() to create a hash string that with the password and salt to be stored in the database. Each time a user tries to login, the password entered would have to be run against this function and compared against the value stored in the database.

For an example of checking if an entered password is valid, check out the valid_password() function.

Addendum:

Special thanks to Julius Beckmann. He provided code to further make the password hashing process more difficult to crack:

// Very complex hash function (GNU)
// Written by: http://juliusbeckmann.de/
// This function is using only sha1() and strrev() which are
// available on every PHP5 installation.
function hash_password($p, $s, $iter=5) {
  // ALWAYS return a multiple hashed pass salt combination
  $hash = sha1(sha1($p.$s).sha1(strrev($p).strrev($s)));

  // Rehashing the hash will make cracking process much slower
  for($i=0;$i< =$iter;++$i)
    $hash = sha1(sha1($hash).sha1(strrev($hash))));

  return $hash;
}

I also added code to generate more complex case-sensitive salt strings then the hexadecimal strings from before:

function generate_salt($length = 20){
  // Purposely left off quotation marks so it doesn't mess with SQL
  $chars =  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
            '0123456789``-=~!@#$%^&*()_+,./<>?;:[]{}\|';

  $str = '';
  $max = strlen($chars) - 1;

  for ($i=0; $i < $length; $i++)
    $str .= $chars[rand(0, $max)];

  return $str;
}

I was helping someone debug a slow query today when I noticed a common mistake that a lot of developers do. He was trying to get a list of users given a list of user id numbers.

The query looks something like this:

SELECT * FROM users
WHERE
  id = 1 OR
  id = 2 OR
  id = 3 OR
  id = 4 OR
  id = 5

For small data sets, SQL queries like the one above are fine. There isn’t much data for MySQL to search through and retrieve. You wouldn’t notice much of a performance hit on your servers at all.

But what if you had over a million users and you need to retrieve records from a list of 50,000 user id numbers? A better way to rewrite the query is to use the IN clause.

SELECT * FROM users
WHERE
  id IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,5000001)

You can also pass in strings and other data types:

SELECT * FROM users
WHERE
  first_name IN ('John', 'Jane', 'James', 'Jack')

You can also do NOT IN:

SELECT * FROM users
WHERE
  first_name NOT IN ('Alex', 'Abby', 'Andy', 'Audrey')

Hope this helps improve your data retrieval times. If anything, it definitely makes for easier to read queries.

Happy querying!

After months of development and incubation, the team at Extract Value was able to release IASG to the world this weekend. I am so proud of the team and the company for pushing out such an amazing, unique, and rich product for the finance industry.

Read more »

AJAX has been the new hotness in web development and the recent web 2.0 craze. By carefully utilizing AJAX, web designers and developers can create a seamless and smooth user experience. Users can continue interacting with a page without breaking the experience with page reloads or redirects.

Lately, I have been asked by many of my web designer friends how to submit a form via AJAX. With jQuery, the process is incredibly simple.

We will use AJAX to submit a very simplified registration form to another PHP page, ajax-register.php. The form will ask the user for their name, their email, and a password. This prevents us from doing any extra logic to check matching passwords.

To download the source code click here. You could also try out a demonstration here.

Update: Modified the code so the form will degrade gracefully if JS is turned off. Special thanks to Erol for pointing this out!

Read more »

Jun 8

Hello world!

Posted in: Blog | 2 Comments

After several days of setting up my server with Slicehost and sweating over all the minor details, I am happy to release my website to the internet.

Read more »

What I do

Expertise PHP
Internet Engineering
Build highly scalable web applications in Ruby on Rails, PHP MVC, and Python / Django.
Expertise2
Frontend Programming
Create shiny websites with CSS, (X)HTML, Javascript, AJAX, and Web 2.0 sugar.
Expertise3
LAMP Administration
Apache, MySQL, Memcache, CRON jobs, and the magic sauce that make web apps tick.
Expertise4
iPhone / OS X Development
Develop applications for iPhone and OS X in Objective-C / Cocoa for kicks and giggles.

View my portfolio »

Popular Posts

Archives

About me

My name is George. I am a Software Engineer with about three years experience developing in open-source internet technology. I currently live and work in Los Angeles, California.

I am currently a Ruby on Rails developer. But the majority of my experience has been in PHP. I have also dabbled in C# / ASP.NET and Python / Django for various projects.

View my résumé or contact me today.

Get in touch!

You may either use my contact form, or send and email to me directly at george@georgetruong.com.

You could also try to reach me at 626-817-2633.

Twitter LinkedIn Google Facebook