We help IT Professionals succeed at work.

key data, how to see expiration length?

Bobby
Bobby asked
on
136 Views
Last Modified: 2019-01-22
The following code is supposed to determine how long it has been since a password reset request was submitted. If the request has expired, disallow.

        } else if(!empty($request->get('key'))) {
          $dbAccessor = new DbAccessor();
          $new_password = $request->get('new_password');
          $rawkey = $dbAccessor->unobfuscate_id($request->get('key'));
          $keyparts = explode(":", $rawkey);
          $contact_id = $keyparts[0];
          $expiration = $keyparts[1];

          if(time() > $expiration) {
             $redirect = "/account/reset_my_password?error=key_expired";

Open in new window


I know it works, because I changed the > to a < in the if(time() > $expiration), and I could not reset my password.

I'm a complete newb at this, taking over for a staff member who moved away. He was our main back end web dev, and Im scrambling to fill his shoes as much as I can.

I was tasked with this because somebody ran across a link that was sent out to a real customer months ago to reset their password. We clicked the link, and it took us to the password reset page, as if it was perfectly fine to reset our password after all those months. The link should have expired.

BUT

This may have been designed so that the user doesn't get a message that it has expired, it just doesnt do what it says (like my test in reversing the <>). That would be perfectly acceptable... not graceful, but at least the password could not be reset via that link 3 months later.

So... obviously I need to figure out the value of this: $keyparts[1]; to see what time value is being specified (if any). How do I see that? Here is the unobfuscate_id function:

   public function unobfuscate_id($str) {  
      $key = "realdatastripped";
      $encrypted_str = base64_decode(str_pad(strtr($str, '-_', '+/'), strlen($str) % 4, '=', STR_PAD_RIGHT));
      $str = mcrypt_decrypt(MCRYPT_DES, $key, $encrypted_str, MCRYPT_MODE_ECB);
      $block = mcrypt_get_block_size('des', 'ecb');
      $pad = ord($str[($len = strlen($str)) - 1]);
      $unencrypted_str = substr($str, 0, strlen($str) - $pad);
      return str_replace("dm", "", $unencrypted_str);

Open in new window


If it helps, here is the key in one email I initiated to myself for a password request: reset_my_password?key=XPLDFLhFhu0O192aM6dmCGhW4srTDUQw
Comment
Watch Question

CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
mcrypt functions have been deprecated.
Trying to run that code gives a warning
Key of size 16 not supported by this algorithm. Only keys of size 8 supported
There is a way to convert to opnessl but it is taking too much time.
Can you add the following to your code (line 8 - or anywhere after line 4).
echo "<pre>" . print_r($rawkey, true) . "</pre>";

Open in new window

Post the results here.

This is a very complicated solution. Another option is just to generate a UUID() (if you are using MySQL or MariaDB you can do it with the UUID() function).
Save this to an activation key table in the DB with a timestamp and userid.
When a key comes in compare timestamp to current time() - if outside expiry period then deny.

Cleanup script runs regularly to clean up table.

The nice thing about this approach is that no information is stored in the key.
The key can't be tampered with.
You can change the expiry time and it will apply to all existing keys.
David FavorFractional CTO
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
Julian is correct, mcrypt has been deprecated. Use libsodium instead.

Also, as Julian said, fixing this will be complex.

My guess is you'll have to fix your code to use libsodium or another supported encryption type.

Once your code is working, this should trigger every user doing a password reset.

Depending on your database table schema, you may also have to run an alter table to change your password field length.

Also version of PHP you're running on today + version your upgrading to will be a factor.
David FavorFractional CTO
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
Since you said, "I'm a complete newb at this" likely best if you hire someone to help you with this.

Also, keep the PHP Compatibility Checker URL handy, as this tool is a must for finding other potential problems in your code which are near impossible to catch by eye.

Also, if your code has a debugging facility, enable it so all problems are logged instantly.

If your code has no debugging facility, this will be one of the first tasks you complete, so you can see all errors/warnings, rather than guess.

Author

Commented:
Julian, I added

echo "<pre>" . print_r($rawkey, true) . "</pre>";

where you said but it does not print to the browser, so I have no results to post.
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Then either the decrypt is not working or the key is not present.

The code after line 8 expects a value in the form
CONTACTID:EXPIRES

If you are not seeing this then the extract of the key is not working.

What version of PHP are you using?

Seriously, I would move away from an encrypted solution - in my view it only complicates your solution. A simple unguessable key (like UUID) linked to database record would work much better.

Author

Commented:
we upgraded about a month ago from php 5.5 to php 7.2
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019

Commented:
Well - that is your problem isn't it.
From here http://php.net/manual/en/function.mcrypt-decrypt.php
This function has been DEPRECATED as of PHP 7.1.0 and REMOVED as of PHP 7.2.0. Relying on this function is highly discouraged.
Your code is never going to work because the mcrypt functions have been removedin 7.2

Author

Commented:
Ugh. Thanks for researching. So, in a nutshell, what do you think our quickest solution will be? I need to take this to the CEO and give him some kind of timeline to getting it fixed.
CERTIFIED EXPERT
Most Valuable Expert 2017
Distinguished Expert 2019
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions