Cookies¶
Some cookies-related features might prevent other extensions from hooking the setcookie function. Pay attention to the loading order of your extensions in this case.
auto_cookie_secure¶
auto_cookie_secure, disabled by default, will automatically mark cookies as secure when the web page is requested over HTTPS.
It can either be enabled
or disabled
.
sp.auto_cookie_secure.enable();
sp.auto_cookie_secure.disable();
cookie_samesite¶
samesite, disabled by default, adds the samesite attribute to cookies. It prevents CSRF but is not implemented by all web browsers yet. Note that this is orthogonal to PHP7.3+ SameSite support.
It can either be set to strict
or lax
:
- The
lax
attribute prevents cookies from being sent cross-domain for “dangerous” methods, likePOST
,PUT
orDELETE
. - The
strict
one prevents any cookies from beind sent cross-domain.
sp.cookie.name("cookie1").samesite("lax");
sp.cookie.name_r("^cookie[0-9]+").samesite("lax");
sp.cookie.name("cookie2").samesite("strict");;
Cookie encryption¶
The encryption is done via the tweetnacl library, thus using curve25519, xsalsa20 and poly1305 for the encryption. We chose this library because of its portability, license (public-domain), simplicity and reduced size (a single .h and .c file.).
- The key is derived from multiple sources, such as:
- The
secret_key
provided in the configuration in thesp.global.secret_key
option. It’s recommended to use something likehead -c 256 /dev/urandom | tr -dc 'a-zA-Z0-9'
as a value. - An optional environment variable, such as
REMOTE_ADDR
(remote IP address) or the extended master secret from TLS connections (RFC7627) in thesp.global.cookie_env_var
option. - The user-agent.
- The
Warning
To use this feature, you must set the global.secret_key variable and should set the global.cookie_env_var one too. This design decision prevents an attacker from trivially bruteforcing or re-using session cookies. If the simulation mode isn’t specified in the configuration, snuffleupagus will drop any request that it was unable to decrypt.
Since PHP doesn’t handle session cookie and non-session cookie in the same way, so does Snuffleupagus.
Session cookie¶
For the session cookie, the encryption happens server-side: Nothing is
encrypted in the cookie: neither the cookie’s name (usually PHPSESSID
) nor
its content (the session’s name). What is in fact encrypted, is the session’s
content, on the server (usually stored in /tmp/sess_<XXXX>
files).
Session encryption, disabled by default, will activate transparent session encryption.
It can either be enabled
or disabled
and can be used in simulation
mode.
sp.session.encrypt();
sp.session.simulation();
Non-session cookie¶
For the non-session cookie, the cookie’s name is left untouched, only its value is encrypted.
Cookie encryption, disabled by default, will activate transparent encryption of specific cookies.
It can either be enabled
or disabled
and can be used in simulation
mode.
sp.cookie.name("my_cookie_name").encrypt();
sp.cookie.name("another_cookie_name").encrypt();
Removing the user-agent part¶
Some web browser extensions, such as uMatrix
might be configured to change the user-agent on a regular basis. If you think that
some of your users might be using configurations like this, you might want to disable
the mixing of the user-agent in the cookie’s encryption key. The simplest way to do
so is to set the environment variable HTTP_USER_AGENT
to a fixed value before passing
it to your php process.
We think that this use case is too exotic to be worth implementing as a proper configuration directive.
Choosing the proper environment variable¶
It’s up to you to choose a meaningful environment variable to derive the key from.
Suhosin is using
the REMOTE_ADDR
one, tying the validity of the cookie to the IP address of the user;
unfortunately, nowadays, people are roaming a lot on their smartphone,
hopping from WiFi to 4G.
This is why we recommend, if possible, to use the extended master secret
from TLS connections (RFC7627)
instead. The will make the validity of the cookie TLS-dependent, by using the SSL_SESSION_ID
variable.
- In Apache,
it is possible to enable by adding
SSLOptions StdEnvVars
in your Apache2 configuration. - In nginx,
you have to use
fastcgi_param SSL_SESSION_ID $ssl_session_id if_not_empty;
.
If you aren’t using TLS (you should be), you can always use the REMOTE_ADDR
one,
or X-Real-IP
if you’re behind a reverse proxy.