How does this PHP nonce library work?

cryptography, hash, php

Solution

Wow, DO NOT USE THIS LIBRARY. I am going to report this as a vulnerability right after this post. A Nonce is a value that is only used once, and this library does provide this. HOWEVER, the author was trying to prevent Cross Site Request Forgeries (XSRF). In order to prevent attackers from forging a message there needs to be a secret value that the attacker can't predict. In order to do this you need a Cryptographically Secure Random Number Generator or CSRPING. The Nonce that this library builds, is extremely predictable and could easily be brute forced using simple javascript.

Problem

From http://fullthrottledevelopment.com/php-nonce-library#download, there is a PHP nonce library, but there are a few things that I don't know understand. The first one is that it reminds us to set a value for the `FT_NONCE_UNIQUE_KEY` but it never uses it in any of its functions. The second thing is, when I call the `ft_nonce_create_query_string` function, wait for a few seconds and then call it again with the same parameters, both calls return the same value. This is strange, I really don't understand how it can make sure for each nonce it generates, the nonce will be valid for the duration specified in the `FT_NONCE_DURATION`. But if I wait for longer time before the second call, they will return different value. I have pasted the codes here so that you can try to run it directly. Why is it like this? How is it supposed to work? ``` <?php /* * Name: FT-NONCE-LIB * Created By: Full Throttle Development, LLC (http://fullthrottledevelopment.com) * Created On: July 2009 * Last Modified On: August 12, 2009 * Last Modified By: Glenn Ansley (glenn@fullthrottledevelopment.com) * Version: 0.2 */ /* Copyright 2009 Full Throttle Development, LLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ define( 'FT_NONCE_UNIQUE_KEY' , '' ); define( 'FT_NONCE_DURATION' , 300 ); // 300 makes link or form good for 5 minutes from time of generation define( 'FT_NONCE_KEY' , '_nonce' ); // This method creates a key / value pair for a url string function ft_nonce_create_query_string( $action = '' , $user = '' ){ return FT_NONCE_KEY."=".ft_nonce_create( $action , $user ); } // This method creates an nonce for a form field function ft_nonce_create_form_input( $action = '' , $user='' ){ echo "<input type='hidden' name='".FT_NONCE_KEY."' value='".ft_nonce_create( $action . $user )."' />"; } // This method creates an nonce. It should be called by one of the previous two functions. function ft_nonce_create( $action = '' , $user='' ){ return substr( ft_nonce_generate_hash( $action . $user ), -12, 10); } // This method validates an nonce function ft_nonce_is_valid( $nonce , $action = '' , $user='' ){ // Nonce generated 0-12 hours ago if ( substr(ft_nonce_generate_hash( $action . $user ), -12, 10) == $nonce ){ return true; } return false; } // This method generates the nonce timestamp function ft_nonce_generate_hash( $action='' , $user='' ){ $i = ceil( time() / ( FT_NONCE_DURATION / 2 ) ); return md5( $i . $action . $user . $action ); } if ( FT_NONCE_UNIQUE_KEY == '' ){ die( 'You must enter a unique key on line 2 of ft_nonce_lib.php to use this library.'); } ?> ```

Original source