When should server side sessions be enabled instead of client side
sessions?
Non riesco a pensare a una situazione in cui vorresti qualcosa di lato client diverso da "user experience".
Gli identificativi di sessione dovrebbero sempre essere lato server, in quanto il server dovrebbe convalidare se la sessione è valida o meno.
Is it safe to put a CSRF-token in a client side cookie, whether it is
encrypted or not?
Un token anti-CSRF dovrebbe contenere dati generati casualmente, questo è molto "meno costoso" di generare una stringa crittografata, purché la stringa sia lunga e abbastanza casuale.
Non penso che sia sufficiente memorizzare il token anti-CSRF in un cookie.
Suggerirei di creare un sistema in cui un token anti-CSRF viene inviato da un campo di input nascosto e viene trasmesso nell'intestazione. Entrambi dovrebbero essere controllati sul lato server.
Ecco un esempio in PHP:
function generateToken($key) {
$token = base64_encode(openssl_random_pseudo_bytes(16));
$_SESSION['csrf_' . $key] = $token;
return $token;
}
function checkToken($key, $value) {
if (!isset($_SESSION['csrf_' . $key]))
return false;
if (!$value)
return false;
if ($_SESSION['csrf_' . $key] !== $value)
return false;
unset($_SESSION['csrf_' . $key]);
return true;
}
if ($_POST and $_POST['action'] == "something")
{
$header_token = apache_request_headers()['X-Anti-Csrf-Token'];
$post_token = $_POST['token'];
$post_token = str_replace(" ", "+", $post_token);
if ($header_token == $post_token)
{
if (checkToken('settings', $post_token))
{
// ok; do something
}
}
else
{
// wrong; do something
}
}
Invio dell'intestazione prima dell'elaborazione:
<script>
$("#some_div").submit(function(event) {
event.preventDefault();
var $form = $(this),
url = $form.attr('action');
var posting = $.ajax(url, {
type: 'POST',
processData: true,
dataType: "text",
beforeSend: function (xhr) {
xhr.setRequestHeader('X-Anti-CSRF-Token', $('#token').val());
}
Questo pezzo di codice genererà il token e lo inserirà in un campo di input nascosto.
<input id="token" type="hidden" value="<?php echo generateToken('settings'); ?>">