3
\$\begingroup\$

I am trying to prevent CSRF for my login page (linked from here), and for this I am going to use a random token generator to create a UUID for the session.

The function that I have so far is as such:

function UUID()
{
 mt_srand((double)microtime()*10000);
 $charid = strtoupper(md5(uniqid(rand(), true)));
 $hyphen = chr(45);
 $uuid = substr($charid, 0, 8).$hyphen
 .substr($charid, 8, 4).$hyphen
 .substr($charid,12, 4).$hyphen
 .substr($charid,16, 4).$hyphen
 .substr($charid,20,12);
 return $uuid;
}

This function is working perfect and on a loop of 30 runs it gives me this result:

E1BDBF20-A481-AD53-648F-C89E5242B934
E2329CE9-B79D-999A-C61F-65C3C3976EBE
B2FE5771-60DE-9E9B-ADF2-1A78B6BD8BC4
77384406-B472-8192-E301-50CCA1E0CC10
7854EF9F-991F-90D9-ACA5-07C01C25F355
EB4D6BC0-6AB1-9020-0C94-BCB81C540EA9
0AAABBCC-B53F-AF23-2D18-92B971AFD76C
298FAE1A-F25A-7BF9-ECA9-3C5E80CCBC82
0533A8D8-AC1F-3A94-FD51-8A95B69DB9C7
CC650B31-14B6-8709-9E6C-84AA307E77DA
52AEE9D4-FAC4-7AEC-DB31-882CA61A6AE6
EED5154B-7425-ED7C-95A1-2239A79F0FAC
42094233-09D7-BB08-8404-908889B5AB6C
1A3C9D28-4FF3-5A4B-1994-AFE189D02C01
4F5D3BC5-C94A-CFD5-87C1-4E2903811DF0
6BC0612C-93EE-DE33-299B-44888BCCC670
D7029641-ED26-C136-C5BB-6A6C932A1354
AB3CF87D-8FA1-C38F-13AA-BFEEA016122C
687DC395-CF5C-2797-F825-9122D179D6B4
7970708B-F266-B308-6DA5-49DB190C9326
ABF5494D-C8B3-976D-42D6-FE108BFF593E
F0A3A1C0-3A57-EED3-54FB-60C644C8F329
7A687548-B0B3-E266-E473-74E9BE6D45BE
A445E134-A9FD-E554-D6E7-E6D1DE9D1046
F8FCE8F8-7B2C-92E4-00B3-9F834BCE1E9A
982E093A-0D93-AEAC-DEC3-EFEFA9401EEE
353E75FC-80B5-6177-F987-4EAF77BC4F97
8262F39E-F4C0-B60B-9007-A533BC043600
3810166A-38AC-1275-2593-922CD25E42C6
59E6A361-8FEA-FE81-B75E-927FC439159E

But it seems like there is a better way of creating this, although I have tried to use com_create_guid, this did not give quite the result I wanted.

asked Jan 6, 2016 at 11:32
\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

I think mt_srand seeds the rng for mt_rand, not for rand. What you probably want is srand. Although seeding it with the time is not that good of an idea, as time is a value an attacker might guess.

But really, there is no reason to use rand in the first place (the documentation also warns against using it when secure values are needed). Just use openssl_random_pseudo_bytes:

base64_encode(openssl_random_pseudo_bytes(32));

I don't really see a reason to place hyphens in-between the characters. It doesn't really add anything. It just makes the token longer, without adding randomness. I also don't see a reason for strtoupper, it even reduces randomness.

Also note that uniqid is not supposed to be used for any security purposes. If we assume that it is completely broken (which it is probably not, but I haven't looked at the code, and it does have a big warning in the documentation), that would only leave you with 10 random numerical characters (from a not-so-great rng), which doesn't seem that great.

I don't think that there is really a security issue with what you have, but it is definitely not the correct approach. Just use openssl_random_pseudo_bytes instead. It's definitely more secure, and the code is considerably shorter, and can easily be adapted (just change 32 to 64 if you want more security; with your code, you would have to change a lot more).

answered Jan 6, 2016 at 12:15
\$\endgroup\$
2
  • \$\begingroup\$ At least I am mostly used to seeing UUID's with hyphens. \$\endgroup\$ Commented Jan 6, 2016 at 13:45
  • 2
    \$\begingroup\$ @SimonForsbergMcFeely good point. UUID is probably the wrong name for a CSRF token anyways (which doesn't need to be universally unique, and doesn't really identify anything). The hyphens are there so it's human readable, but that's really not needed for a CSRF token. \$\endgroup\$ Commented Jan 6, 2016 at 13:55

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.