0
votes

I am making a CakePHP 2.2.3 application that needs to depend on another existing application for its login information. The username/password combinations exist on another database/server, and I've set up my CakePHP app to create new users upon them logging into my interface for the first time. Here's the process:

  1. User Logs in for the first time, supplies username & password. CakePHP user record does not exist yet
  2. System checks to see if a user with the same (sanitized) username exists on the other side
  3. If a user does exist, then we fetch the password and compare the passwords to see if they match.
  4. If the passwords match, hash what's been provided and save the user record
  5. Log in the newly created user

This solves a few problems for us, chiefly having multiple places for the user to log in to do certain things.

My problem appears to be that the value CakePHP gets when it hashes the passwords seems to change over time. So instead of logging the user in with their password, it creates a new user record every next day they log in. I experienced an issue where I couldn't log in with a particular user yesterday... so I checked to see what the login() action saw as the hashed value of the password was.

The particular user's password is 'roads'

Yesterday, the hash was: 988042d7f4e62760238d895472ecaf1844094f9f

Today, when I hash roads I get: a8318e7bbe8ee5efc59f53b4ede4d80dc0495c6d

I really have no idea where to start looking to see why this would occur. For purposes of getting my development moving forward all I can do is change the hashed value of the password for the user record I want to log in as. This is the second day I'll have done this. Is there anything I could have done wrong with the Security hash or salt value in the config/core.php?

I would love to either:

  1. Figure out why the hashes are changing
  2. Change the Auth component to use the other database to log users in

But I'm not sure where to start on either of those

2
1. I have never heard of the hash changing on it's own. Are you and another developer working and uploading 2 diff. versions of the core.php file? 2. let's see the code you use to get the hashed version of roads. 3. what cake version are you using? - Tim Joyce
In app/Config/core.php its defined the salt. Where it says Configure::write('Security.salt', 'xxxxx...'); But it is always the same. - Alvaro
Temporarily log the parameters passed to Security::hash, they could be telling. For example, perhaps one function/action is using a different hash algorithm or even a different salt. Lastly, if you write some unit tests and they will likely reveal what's happening. - jeremyharris

2 Answers

1
votes

I can't tell what the problem is, but I can tell you where to look. The AuthComponent in CakePHP uses the Security class to do password hashing.

public static function password($password) {
    return Security::hash($password, null, true);
}

This is telling the Security class to hash your password with the default algorithm and to use the salt configured in Security.salt. If the value of Security.salt is different in either application the hash will not match.

The second possibility is that when create the user record you are not using the same settings to Security::hash as AuthComponent. Check that you aren't specifying a different algorithm or providing a salt.

The third possibility is that one application is missing a hashing algorithm. For example if sha1 is available on your login application, but not on your database application, the hashes will not match. The database application will fall back to sha256 and the login application will use sha1.

0
votes

This can happen if you're performing certain acrobatics in a crud-style update function. Basically, what can happen is that you're saving the password twice. You've probably got some code in your model like:

public function beforeSave($options = array()) {
    if(isset($this->data[$this->alias]['password'])) {
    $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
    }
return true;
}

Which guarantees that any password data attached to the model is going to get hashed before it's sent to the DB, as a security precaution. BUT, if you call anything like $this->MyModel->read(null, $someId) in your update function, you're going to set the entirety of your record's data on the Model -including the previously hashed password- and your code will dutifully hash it a second time, which is clearly not what you want. So yes, under these kinds of circumstances you'll get hash-drift.