0

I know perfectly well that preventing tampering with a form is impossible.

But I want to ask, by implementing this function that generates a random number in a page hosting a form and echoing it in a hidden input field

function makeRandomString($bits = 256) {
    $bytes = ceil($bits / 8);
    $return = '';
    for ($i = 0; $i < $bytes; $i++) {
        $return .= chr(mt_rand(0, 255));
    }
    return $return;
}

if at the time of submitting, I checked with a query if that code already exists in the table of random_codes created before, if it exists, it blocks everything, and if it does not exist, it inserts it and executes the query.

Could that be a good thing?

Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59
user18021023
  • 3
  • 1
  • 3
  • 1
    Does this answer your question? [How to properly add cross-site request forgery (CSRF) token using PHP](https://stackoverflow.com/questions/6287903/how-to-properly-add-cross-site-request-forgery-csrf-token-using-php) – executable Jan 27 '22 at 15:16

1 Answers1

1

You should not create your custom implementation, there are already well-known solutions to this problem in pretty much every language and framework.

A few obvious issues with your method:

  • mt_rand() is not cryptographically random and should not be used for this purpose
  • if you store the generated values in a table, an attacker can store their own values to the same table and use it in the context of a victim user's session, unless these values are also tied to an actual user
  • this will require a separate database lookup to check this token every single time (instead of storing it in the session)
  • you have not mentioned invalidating these values, would they be single use and deleted when received? that would be a UX disaster especially with javascript-heavy applications, and also a potential race condition
  • some of the characters generated will not be printable which might cause issues with hidden fields
  • (if the $bits parameter is not disivisble by 8, you will generate more bits, which is very counter-intuitive)
  • and so on...

It's a lot easier to just use a known good implementation, rolling your own is trickier than you might think.

Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59