{
    "href": "/post/2013/02/13/for-csrf-tokens-mt-rand-is-ok-ish-but-openssl-random-pseudo-bytes-is-a-lot-better/",
    "relId": "2013/02/13/for-csrf-tokens-mt-rand-is-ok-ish-but-openssl-random-pseudo-bytes-is-a-lot-better",
    "title": "For CSRF tokens, mt_rand() is ok-ish but openssl_random_pseudo_bytes() is a lot better",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "href": "/tag/aura/",
            "relId": "aura",
            "title": "Aura",
            "author": null,
            "created": "2020-09-14 21:51:57 UTC",
            "updated": [
                "2020-09-14 21:51:57 UTC"
            ],
            "markup": "markdown"
        },
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/programming/",
            "relId": "programming",
            "title": "Programming",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/security/",
            "relId": "security",
            "title": "Security",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        }
    ],
    "created": "2013-02-13 17:30:30 UTC",
    "updated": [
        "2013-02-13 17:30:30 UTC"
    ],
    "html": "<blockquote>\n<p>On the pages for rand() and uniqid(), as well as looking at the C code, they specifically state that these functions should not be used for generating secure tokens. \u00c2\u00a0They tend to generate predictable values. \u00c2\u00a0And the documentation for md5() states that it should not be used for password hashing. \u00c2\u00a0Granted we\u00e2\u0080\u0099re not hashing passwords when creating a CSRF token, but with the tooling available shouldn\u00e2\u0080\u0099t we be using functions that are more cryptographically secure?</p>\n<p>...</p>\n<p>The goal here is the random value. \u00c2\u00a0As such the hashing using hash_hmac() does not buy you a whole lot extra. \u00c2\u00a0The number of possible values in a 32 byte random string is\u00c2\u00a01.1579208923731619542357098500869e+77. \u00c2\u00a0That alone would seem to be enough for a CSRF prevention token. \u00c2\u00a0mt_rand() returns an integer which gives you \u00c2\u00a0about 4 billion possible numbers. \u00c2\u00a0While that will probably protect you, the other value will offer you better protection. \u00c2\u00a0There\u00e2\u0080\u0099s no sense in gambling with a smaller value if you have the ability to generate a larger value with virtually no additional cost.</p>\n<p>So it would seem that, for generating a proper token the code that you would really need is this:</p>\n<pre><code>$token = base64_encode( openssl_random_pseudo_bytes(32));</code></pre>\n<p>The only reason for the base64_encode() call is to make sure that the value provided will not break your HTML layout.</p>\n</blockquote>\n<p>Looks like we need to update <a href=\"https://github.com/auraphp/Aura.Session\">Aura.Session</a> to use openssl when available and fall back to mt_rand() when it's not.  Via <a href=\"http://www.eschrade.com/page/generating-secure-cross-site-request-forgery-tokens-csrf/\">Generating secure cross site request forgery tokens (csrf)</a>.</p>\n"
}
