https://github.com/xp-forge/cookie-sessions
Cookie-based sessions
https://github.com/xp-forge/cookie-sessions
cookie-session php7 php8 sessions web xp-framework
Last synced: 5 months ago
JSON representation
Cookie-based sessions
- Host: GitHub
- URL: https://github.com/xp-forge/cookie-sessions
- Owner: xp-forge
- Created: 2022-05-30T20:44:19.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-24T10:26:44.000Z (about 2 years ago)
- Last Synced: 2025-03-12T23:02:12.324Z (about 1 year ago)
- Topics: cookie-session, php7, php8, sessions, web, xp-framework
- Language: PHP
- Homepage:
- Size: 30.3 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
Awesome Lists containing this project
README
Cookie sessions for the XP Framework
========================================================================
[](https://github.com/xp-forge/cookie-sessions/actions)
[](https://github.com/xp-framework/core)
[](https://github.com/xp-framework/core/blob/master/LICENCE.md)
[](http://php.net/)
[](http://php.net/)
[](https://packagist.org/packages/xp-forge/cookie-sessions)
Cookie-based session implementation for the [sessions library](https://github.com/xp-forge/sessions/pull/10). Purely client-side, they require no serverside storage and thus scale very well. However, they also come with downsides, [discussed below](https://github.com/xp-forge/cookie-sessions#security).
Usage
-----
Inside the routing setup:
```php
use web\session\CookieBased;
use web\auth\SessionBased;
use util\Secret;
$secret= new Secret('y+lCLaMzxlnHjkTt3FoPVQ_x5XTHSr78'); // 32 bytes!
$sessions= new CookieBased($secret);
$auth= new SessionBased($flow, $sessions);
return $auth->required(function($req, $res) {
// Use $req->value('user')
});
```
A binary-safe 32 byte secret key can be generated using the following:
```bash
$ xp -d 'base64_encode(random_bytes(24))'
string(32) "ai4BO6rpwgezJztTalg5rt29XNJwMRMQ"
```
Security
--------
As stated [here](https://github.com/SaintFlipper/EncryptedSession#why-use-server-side-session-storage-instead-):
> [The] security risk of putting the session data in the session cookie is the danger of "session replay" attacks. If a valid session cookie is captured from a user's browser (it's visible in the browser's developer console) then that cookie can be copied to another machine and used in a rogue session at any time.
Though the same applies for server-side sessions with session IDs transmitted via cookies, we can destroy the attached session on the server-side to invalidate in these cases, e.g. by deleting the session file or removing the relevant row from the database. For cookie-based sessions, there is no way to remotely guarantee session destruction - and thus no way for a safe user-based "Log me off on all devices" functionality.
However, if we use cookie-based sessions to store short-lived access tokens, we can reduce this risk significantly: A replay can only occur during that window of time. For Microsoft 365, this time is roughly one hour.
👉 **Long story short**: If there's an easy possibility to use server-side sessions, do that. If dependencies come at a high cost and you have ways of managing the risk, or for development purposes, this implementation can be a valid choice.
Internals
---------
The session data is encrypted in the cookie and then encoded in base64 to use 7 bit only. The first byte controls the algorithm used:
* `S` for Sodium, using [sodium_crypto_box_open()](https://www.php.net/sodium_crypto_box_open), requires Sodium extension
* `O` for OpenSSL, using [openssl_encrypt()](https://www.php.net/openssl_encrypt), requires OpenSSL extension
The encrypted value is signed by a hash to detect any [bit flipping attacks](https://en.wikipedia.org/wiki/Bit-flipping_attack).
Compression
-----------
To prevent hitting the [browser cookie limits](http://browsercookielimits.iain.guru/) too early, the cookie values are compressed using LZW (*which is [relatively easy to implement](http://www.rosettacode.org/wiki/LZW_compression#Simpler_Version) and gives good savings without requiring an extra PHP extension compiled in*) if it's deemed worthwhile. If the cookie value is compressed, the indicators above appear in lowercase (`s` and `o` instead of `S` and `O`).
An example:
* JSON value (response from `https://api.twitter.com/1.1/account/verify_credentials.json`): **2814 bytes**
* Encrypted and encoded cookie value: **3807 bytes** (*pretty close to the limit!*)
* If compressed, decreases to **2477 bytes** (*more than a kilobyte saved, 65% of the size*)
See also
--------
* https://github.com/SaintFlipper/EncryptedSession
* https://blog.miguelgrinberg.com/post/how-secure-is-the-flask-user-session