Ordered UUIDs (v7) for session ID for noticeable performance boost and compatibility with other systems #45132
Replies: 4 comments 1 reply
-
I'd certainly like to see this. Have been doing a lot of research on ULIDs, UUIDv7, etc. and looks to be the way of the future. |
Beta Was this translation helpful? Give feedback.
-
Any chance this will be implemented? Just being able to customize the format would be great. I like how ordered uuids or ulids let you infer creation time even when using a backend like redis that doesn’t have that by default. |
Beta Was this translation helpful? Give feedback.
-
My understanding is you want session IDs to be completely random, and have no guessability. By using something like UUID v7 you now introduce a timestamp into the start, which makes them more predictable and open to attack. So while there may be performance improvements, there are added security risks that probably aren't worth it. |
Beta Was this translation helpful? Give feedback.
-
@browner12 UUID v7 still has (I think) 74 bits of randomness; this is quite difficult for an attacker to guess even if they knew exact timestamp. UUID v7 is nice since it is standardized and permits native UUID DB storage, but if you're not concerned about that then you could still have a scheme which generates ordered IDs with more entropy by retaining the 40-character alphanumeric structure of the current IDs. Laravel also encrypts the session cookie so there's an added layer of defense: an attacker must not only guess the session ID but also steal the application key in order to impersonate a session (I think; not a Laravel expert!). |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi all,
Currently Laravel uses a 40 character random string to generate a session ID. When strings are the primary key in a database, that has heavy indexing performance costs compared to other options available This was also a problematic performance issue with "un-ordered" UUIDs (v4) that were initially stored in strings. That was addressed by using "ordered" UUIDs (v7) stored in the uuid column type. This eliminates the index from being completely re-built after every record insert and the index memory/storage footprint is less than half. As sessions are typically temporary data, I'm suggesting that UUID (v7) would be a great fit to make the default generated session ID. I see that version 10 of laravel already has moved into using version 7 uuids. #44311
I've only used the 'database' and 'file' session options in
config/session.php
so I don't know how this would affect 'cookie', 'apc', 'memcached', 'redis', 'dynamodb' or 'array' options but the generateSessionId() method in Illuminate/Session/Store.php could change it's behaviour based on the selection.If an ID works with any of those, it would be changing the following methods in
Illuminate\Session\Store.php
to be:Then in the
Illuminate\Session\Console\stubs\database.stub
change the 'id' field to be:instead of:
For those upgrading to the new version who still have sessions using the 40 character string, if they are using a database they'd need to change the primary table from a string type to a uuid column type to take advantage of the best indexing performance, however as you can store a UUID in a string, it might just continue to work. If that was the case, you could wait until every session ID in the table is eventually a uuid and then run something like the following (in postgresql at least):
You couldn't migrate it over using the above command if there are still 40 character strings as that won't convert over to a UUID so I expect it would halt.
Ideally, we'd provide a SESSION_ID_TYPE setting in .env where a user could choose one of the following:
Not sure if there are other common formats used. Putting this option in then also messes with the database stub file too making it more complex to create it with the correct column type.
I'm open to feedback and can write the code and create the PR if desired, just give me pointers on whether I create a branch first, etc.
Beta Was this translation helpful? Give feedback.
All reactions