Valider a4864ee9 rédigé par marcimat's avatar marcimat Validation de marcimat
Parcourir les fichiers

change: Gestion des options de cookies

- Mettre l’option 'secure' à `true` dès qu’on est en HTTPS
- Mettre l’option 'secure' à `true` si la constante `_COOKIE_SECURE` est définie (mais deprecated)
  (auparavent uniquement sur les cookies _COOKIE_SECURE_LIST + spip_session);
- Appeler la plupart des cookies pour SPIP avec l’option 'httponly' à `true`
- Déprecier la constante `_COOKIE_SECURE_LIST` (utiliser l’option 'httponly' à `true` sur les appels concernés)

Refs: #5552
parent e824ceb6
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+2 −6
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -63,9 +63,7 @@ function action_converser_changer_langue($update_session) {
			$GLOBALS['visiteur_session']['lang'] = $lang;
			$session = charger_fonction('session', 'inc');
			if ($spip_session = $session($GLOBALS['visiteur_session'])) {
				spip_setcookie('spip_session', $spip_session, [
					'expires' => time() + 3600 * 24 * 14
				]);
				spip_setcookie('spip_session', $spip_session, time() + 3600 * 24 * 14, httponly: true);
			}
		}
		action_converser_post($lang, true);
@@ -89,9 +87,7 @@ function action_converser_post($lang, $ecrire = false) {
				'expires' => time() + 365 * 24 * 3600
			]);
			if ($ecrire) {
				spip_setcookie('spip_lang_ecrire', $_COOKIE['spip_lang_ecrire'] = $lang, [
					'expires' => time() + 365 * 24 * 3600
				]);
				spip_setcookie('spip_lang_ecrire', $_COOKIE['spip_lang_ecrire'] = $lang, time() + 365 * 24 * 3600, httponly: true);
			}
		}
	}
+8 −7
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -88,7 +88,7 @@ function action_cookie_dist($set_cookie_admin = null, $change_session = null) {
		// puis de passer au login qui diagnostiquera l'echec de cookie
		// le cas echeant.
		if ($test_echec_cookie == 'oui') {
			spip_setcookie('spip_session', 'test_echec_cookie');
			spip_setcookie('spip_session', 'test_echec_cookie', httponly: true);
			if ($redirect) {
				$redirect = parametre_url(
					parametre_url($redirect_echec, 'var_echec_cookie', 'oui', '&'),
@@ -102,16 +102,17 @@ function action_cookie_dist($set_cookie_admin = null, $change_session = null) {
			// Suppression cookie d'admin ?
			if ($set_cookie_admin == 'non') {
				if ($cook) {
					spip_setcookie('spip_admin', $cook, [
						'expires' => time() - 3600 * 24
					]);
					spip_setcookie('spip_admin', $cook, time() - 3600 * 24, httponly: true);
				}
			} // Ajout de cookie d'admin
			else {
				if ($set_cookie_admin && _DUREE_COOKIE_ADMIN) {
					spip_setcookie('spip_admin', $set_cookie_admin, [
						'expires' => time() + max(_DUREE_COOKIE_ADMIN, 2 * _RENOUVELLE_ALEA)
					]);
					spip_setcookie(
						'spip_admin',
						$set_cookie_admin,
						time() + max(_DUREE_COOKIE_ADMIN, 2 * _RENOUVELLE_ALEA),
						httponly: true
					);
				}
			}
		}
+1 −3
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -72,9 +72,7 @@ function action_logout_dist() {
		if (isset($_COOKIE['spip_session'])) {
			$session = charger_fonction('session', 'inc');
			$session($GLOBALS['visiteur_session']['id_auteur']);
			spip_setcookie('spip_session', $_COOKIE['spip_session'], [
				'expires' => time() - 3600
			]);
			spip_setcookie('spip_session', $_COOKIE['spip_session'], time() - 3600, httponly: true);
		}
		// si authentification http, et que la personne est loge,
		// pour se deconnecter, il faut proposer un nouveau formulaire de connexion http
+42 −39
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -30,7 +30,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 *     Nom du cookie
 * @param string $value
 *     Valeur à stocker
 * @param array $options
 * @param array{expires: int, path: string, domain: string, secure: bool, samesite: string} $options
 *     Tableau clé => valeur de l’option
 *     - expires = 0 : Date d'expiration du cookie (timestamp)
 *     - path = 'AUTO' : Chemin sur lequel le cookie sera disponible
@@ -50,53 +50,56 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 *   param bool $secure
 *     cookie sécurisé ou non ?
 **/
function spip_setcookie($name = '', $value = '', $options = []) {
	static $to_secure_list = ['spip_session'];
	if (defined('_COOKIE_SECURE_LIST') && is_array(_COOKIE_SECURE_LIST)) {
		$to_secure_list = array_merge($to_secure_list, _COOKIE_SECURE_LIST);
	}

	if (!is_array($options)) {
		// anciens paramètres :
		# spip_setcookie($name = '', $value = '', $expire = 0, $path = 'AUTO', $domain = '', $secure = '')
		$opt = func_get_args();
		$opt = array_slice($opt, 2);
		$options = []; # /!\ après le func_get_args (sinon $opt[0] référence la nouvelle valeur de $options !);
		if (isset($opt[0])) {
			$options['expires'] = $opt[0];
		}
		if (isset($opt[1])) {
			$options['path'] = $opt[1];
		}
		if (isset($opt[2])) {
			$options['domain'] = $opt[2];
		}
		if (isset($opt[3])) {
			$options['secure'] = $opt[3];
		}
// function spip_setcookie($name = '', $value = '', $options = []) {
function spip_setcookie(
	string $name = '',
	string $value = '',
	int|array $expires_or_options = 0,
	string $path = '',
	string $domain = '',
	bool $secure = false,
	bool $httponly = false
) {
	if (!is_array($expires_or_options)) {
		# anciens paramètres : spip_setcookie($name = '', $value = '', $expire = 0, $path = 'AUTO', $domain = '', $secure = '')
		$options = [
			'expires' => (int) $expires_or_options,
			'path' => $path,
			'domain' => $domain,
			'secure' => $secure,
			'httponly' => $httponly,
		];
	} else {
		$options = $expires_or_options;
	}

	// expires
	if (!isset($options['expires'])) {
		$options['expires'] = 0;
	}
	$options['expires'] ??= 0;
	if (!isset($options['path']) || $options['path'] === 'AUTO') {
		$options['path'] = defined('_COOKIE_PATH') ? _COOKIE_PATH : preg_replace(',^\w+://[^/]*,', '', url_de_base());
		$options['path'] = defined('_COOKIE_PATH') ? constant('_COOKIE_PATH') : preg_replace(',^\w+://[^/]*,', '', url_de_base());
	}
	if (empty($options['domain']) && defined('_COOKIE_DOMAIN') && _COOKIE_DOMAIN) {
		$options['domain'] = _COOKIE_DOMAIN;
	if (empty($options['domain']) && defined('_COOKIE_DOMAIN') && constant('_COOKIE_DOMAIN')) {
		$options['domain'] = constant('_COOKIE_DOMAIN');
	}
	if (in_array($name, $to_secure_list)) {
		if (empty($options['secure']) && defined('_COOKIE_SECURE') && _COOKIE_SECURE) {
	$options['secure'] ??= false;
	$options['secure'] = ($options['secure'] ?: ($_SERVER['HTTPS'] ?? false));
	if (defined('_COOKIE_SECURE') && constant('_COOKIE_SECURE')) {
		trigger_deprecation('spip', '5.0', 'Using "%s" constant is deprecated, use option "%s" when call "%s" instead (automatic in HTTPS).', '_COOKIE_SECURE', 'secure: true', __FUNCTION__);
		$options['secure'] = true;
	}
		if (empty($options['httponly'])) {
	$options['httponly'] ??= false;
	$options['samesite'] = ($options['samesite'] ?? 'Lax') ?: 'Lax';

	/** @deprecated 5.0 Use option `'httponly' => true` */
	if (defined('_COOKIE_SECURE_LIST')) {
		trigger_deprecation('spip', '5.0', 'Using "%s" constant is deprecated, use option "%s" when call "%s" instead.', '_COOKIE_SECURE_LIST', 'httponly: true', __FUNCTION__);
		if (
			is_array(constant('_COOKIE_SECURE_LIST'))
			&& in_array($name, constant('_COOKIE_SECURE_LIST'))
		) {
			$options['httponly'] = true;
		}
	}
	if (empty($options['samesite'])) {
		$options['samesite'] = 'Lax';
	}

	// in fine renommer le prefixe si besoin
	if (str_starts_with($name, 'spip_')) {
+8 −9
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -218,9 +218,7 @@ function ajouter_session($auteur) {
	// poser le cookie de session SPIP
	include_spip('inc/cookie');
	$duree = definir_duree_cookie_session($auteur);
	spip_setcookie('spip_session', $_COOKIE['spip_session'], [
		'expires' => time() + $duree
	]);
	spip_setcookie('spip_session', $_COOKIE['spip_session'], time() + $duree, httponly: true);
	spip_log("ajoute session $fichier_session cookie $duree", 'session');

	// Si on est admin, poser le cookie de correspondance
@@ -228,14 +226,15 @@ function ajouter_session($auteur) {
		include_spip('inc/autoriser');
	}
	if (autoriser('ecrire', '', '', $auteur) and _DUREE_COOKIE_ADMIN) {
		spip_setcookie('spip_admin', '@' . ($auteur['email'] ?: $auteur['login']), [
			'expires' => time() + max(_DUREE_COOKIE_ADMIN, $duree)
		]);
		spip_setcookie(
			'spip_admin',
			'@' . ($auteur['email'] ?: $auteur['login']),
			time() + max(_DUREE_COOKIE_ADMIN, $duree),
			httponly: true
		);
	} // sinon le supprimer ...
	else {
		spip_setcookie('spip_admin', '', [
			'expires' => 1
		]);
		spip_setcookie('spip_admin', '', 1, httponly: true);
	}

	# on en profite pour purger les vieilles sessions anonymes abandonnees
Chargement en cours