Version in base suite: 4.4.21+dfsg-0+deb13u1 Base version: spip_4.4.21+dfsg-0+deb13u1 Target version: spip_4.4.23+dfsg-0+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/spip/spip_4.4.21+dfsg-0+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/spip/spip_4.4.23+dfsg-0+deb13u1.dsc CHANGELOG.md | 8 composer.lock | 24 +- debian/changelog | 13 + ecrire/CHANGELOG.md | 37 ++++ ecrire/action/session.php | 13 + ecrire/balise/formulaire_.php | 4 ecrire/base/connect_sql.php | 5 ecrire/inc/cvt_autosave.php | 6 ecrire/inc/modeles.php | 84 ++++++++++ ecrire/inc/urls.php | 25 ++ ecrire/inc/utils.php | 7 ecrire/inc_version.php | 18 +- ecrire/paquet.xml | 3 ecrire/public/balises.php | 11 - ecrire/public/cacher.php | 7 ecrire/public/compiler.php | 1 ecrire/public/composer.php | 3 ecrire/public/fonctions.php | 68 +++++++- ecrire/public/sandbox.php | 8 ecrire/src/Texte/Collecteur/AbstractCollecteur.php | 31 ++- plugins-dist.json | 14 - plugins-dist/bigup/CHANGELOG.md | 6 plugins-dist/bigup/formulaires/tester_bigup.php | 5 plugins-dist/bigup/formulaires/tester_bigup_extended.php | 4 plugins-dist/bigup/paquet.xml | 2 plugins-dist/compresseur/CHANGELOG.md | 6 plugins-dist/compresseur/compresseur_pipeline.php | 3 plugins-dist/compresseur/paquet.xml | 2 plugins-dist/compresseur/phpstan-baseline.neon | 7 plugins-dist/filtres_images/CHANGELOG.md | 6 plugins-dist/filtres_images/filtres/images_lib.php | 1 plugins-dist/filtres_images/paquet.xml | 2 plugins-dist/forum/CHANGELOG.md | 19 ++ plugins-dist/forum/base/forum.php | 16 - plugins-dist/forum/formulaires/forum.php | 47 ++--- plugins-dist/forum/formulaires/forum_prive.php | 33 ++- plugins-dist/forum/forum_autoriser.php | 4 plugins-dist/forum/forum_fonctions.php | 68 ++++++-- plugins-dist/forum/paquet.xml | 2 plugins-dist/forum/phpstan-baseline.neon | 16 + plugins-dist/forum/public/forum.php | 4 plugins-dist/medias/CHANGELOG.md | 12 + plugins-dist/medias/action/ajouter_documents.php | 13 - plugins-dist/medias/formulaires/joindre_document.php | 34 +++- plugins-dist/medias/inc/documents.php | 4 plugins-dist/medias/medias_autoriser.php | 8 plugins-dist/medias/paquet.xml | 2 plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation.html | 4 plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation_fonctions.php | 11 + plugins-dist/textwheel/CHANGELOG.md | 6 plugins-dist/textwheel/inc/texte.php | 2 plugins-dist/textwheel/paquet.xml | 2 plugins-dist/urls_etendues/CHANGELOG.md | 8 plugins-dist/urls_etendues/action/editer_url.php | 10 + plugins-dist/urls_etendues/formulaires/editer_url_objet.php | 30 +++ plugins-dist/urls_etendues/paquet.xml | 2 plugins-dist/urls_etendues/phpstan-baseline.neon | 19 ++ plugins-dist/urls_etendues/prive/objets/editer/url.html | 2 plugins-dist/urls_etendues/urls/arbo.php | 6 plugins-dist/urls_etendues/urls_autoriser.php | 23 ++ plugins-dist/urls_etendues/urls_fonctions.php | 3 prive/CHANGELOG.md | 17 ++ prive/formulaires/mot_de_passe.php | 19 ++ prive/formulaires/oubli.php | 13 + prive/objets/liste/auteurs_associer.html | 4 prive/themes/spip/lists.css.html | 4 vendor/composer/installed.json | 28 +-- vendor/composer/installed.php | 24 +- 68 files changed, 761 insertions(+), 192 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpnx1q5fi4/spip_4.4.21+dfsg-0+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpnx1q5fi4/spip_4.4.23+dfsg-0+deb13u1.dsc: no acceptable signature found diff -Nru spip-4.4.21+dfsg/CHANGELOG.md spip-4.4.23+dfsg/CHANGELOG.md --- spip-4.4.21+dfsg/CHANGELOG.md 2026-08-20 11:46:58.000000000 +0000 +++ spip-4.4.23+dfsg/CHANGELOG.md 2026-09-02 12:02:52.000000000 +0000 @@ -1,5 +1,13 @@ # Changelog +## 4.4.23 - 2026-09-02 + +- Mise à jour des dépendances (ecrire, prive, bigup, forum, medias) + +## 4.4.22 - 2026-09-01 + +- Mise à jour des dépendances (ecrire, prive, compresseur, images, forum, medias, tw, urls) + ## 4.4.21 - 2026-08-20 - Mise à jour des dépendances (ecrire, images) diff -Nru spip-4.4.21+dfsg/composer.lock spip-4.4.23+dfsg/composer.lock --- spip-4.4.21+dfsg/composer.lock 2026-08-20 11:46:58.000000000 +0000 +++ spip-4.4.23+dfsg/composer.lock 2026-09-02 12:02:52.000000000 +0000 @@ -317,16 +317,16 @@ }, { "name": "spip/ecrire", - "version": "4.4.21", + "version": "4.4.23", "source": { "type": "git", "url": "https://git.spip.net/spip/ecrire.git", - "reference": "be104d012aceda0049347121ddc2477c91a79487" + "reference": "f315d717675c54ad2c84411bb8c2d3c26297a0b5" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=be104d012aceda0049347121ddc2477c91a79487", - "reference": "be104d012aceda0049347121ddc2477c91a79487", + "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=f315d717675c54ad2c84411bb8c2d3c26297a0b5", + "reference": "f315d717675c54ad2c84411bb8c2d3c26297a0b5", "shasum": "" }, "require": { @@ -362,23 +362,23 @@ ], "description": "Noyau de SPIP", "support": { - "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.21", + "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.23", "issues": "https://git.spip.net/spip/ecrire/-/issues" }, - "time": "2026-08-20T13:41:29+02:00" + "time": "2026-09-02T13:56:18+02:00" }, { "name": "spip/prive", - "version": "1.1.3", + "version": "1.1.5", "source": { "type": "git", "url": "https://git.spip.net/spip/prive.git", - "reference": "7679959803b8e40ae029a15f757c4ae171802cae" + "reference": "7ed90bbcf72fc33213bc0257bc3e805bd6c5a067" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=7679959803b8e40ae029a15f757c4ae171802cae", - "reference": "7679959803b8e40ae029a15f757c4ae171802cae", + "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=7ed90bbcf72fc33213bc0257bc3e805bd6c5a067", + "reference": "7ed90bbcf72fc33213bc0257bc3e805bd6c5a067", "shasum": "" }, "require-dev": { @@ -390,10 +390,10 @@ ], "description": "Squelettes de l'espace privé", "support": { - "source": "https://git.spip.net/spip/prive/-/tree/1.1.3", + "source": "https://git.spip.net/spip/prive/-/tree/1.1.5", "issues": "https://git.spip.net/spip/prive/-/issues" }, - "time": "2026-08-12T11:11:37+02:00" + "time": "2026-09-02T13:45:16+02:00" }, { "name": "spip/security", diff -Nru spip-4.4.21+dfsg/debian/changelog spip-4.4.23+dfsg/debian/changelog --- spip-4.4.21+dfsg/debian/changelog 2026-08-20 12:06:22.000000000 +0000 +++ spip-4.4.23+dfsg/debian/changelog 2026-09-03 05:41:44.000000000 +0000 @@ -1,8 +1,20 @@ +spip (4.4.23+dfsg-0+deb13u1) trixie-security; urgency=medium + + [ David Prévot ] + * Document CVE in previous changelog entry + + [ Matthieu Marcillaud ] + * build: up dependencies + * build: Version 4.4.23 + + -- David Prévot Thu, 03 Sep 2026 07:41:44 +0200 + spip (4.4.21+dfsg-0+deb13u1) trixie-security; urgency=medium [ Matthieu Marcillaud ] * build: up dependencies * build: Version 4.4.21 + + Fix execution of arbitrary code [CVE-2026-77806] -- David Prévot Thu, 20 Aug 2026 14:06:22 +0200 @@ -11,6 +23,7 @@ [ Matthieu Marcillaud ] * build: up dependencies * build: Version 4.4.20 + + Fix execution of arbitrary code [CVE-2026-77647] -- David Prévot Tue, 18 Aug 2026 12:59:28 +0200 diff -Nru spip-4.4.21+dfsg/ecrire/CHANGELOG.md spip-4.4.23+dfsg/ecrire/CHANGELOG.md --- spip-4.4.21+dfsg/ecrire/CHANGELOG.md 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/CHANGELOG.md 2026-09-02 11:56:18.000000000 +0000 @@ -2,6 +2,43 @@ Changelog de SPIP 4.4 +## 4.4.23 - 2026-09-02 + +### Security + +- spip-security/securite#4907 si le texte est plus long que 8ko on echappe tous les < car on n’est pas certain que le collecteur va trouver tous les modèles +- spip-security/securite#4907 les modèles interdit sont bloqués sans dentelle +- spip-security/securite#4907 ne pas interrompre la recherche sur un preg_match echoué, cela peut venir d'une erreur de preg + +### Fixed + +- #173 rétablir l'appel au filtre insert_head_css_conditionnel +- #170 conditionner le log d'erreur de connection pour les boucles DATA +- autosave: ne pas supprimer abusiment les antislash `\` + +## 4.4.22 - 2026-09-01 + +### Security + +- spip-security/securite#4906 dans les formulaires les champs _xxx permettent d'injecter du html ou du js mais pas plus +- spip-security/securite#4901 si on a un HTTP_X_FORWARDED_HOST différent de HTTP_HOST on l'utilise mais on ne lui fait confiance que si il est connu +- spip-security/securite#4900 urlencode() plus facilement les chaines dans safe_export_env() + +### Added + +- spip-security/securite#4902 fonction `urls_type_objet_valide()` pour vérifier si un type correspond à un objet URL-able +- spip-security/securite#4902 Liste d’autorisation et d’interdiction des modèles SPIP pour les contributions publiques + +### Fixed + +- Éviter de générer du cache avec des contextes empoisonnés par du PHP +- spip-security/securite#4900 ne pas se fier qu'a la regexp et s'assurer que la directive header() est la seule chose de ce bloc PHP +- Dépréciation PHP 8.4 sur ReflectionMethod + +### Changed + +- Signer les filtres insérés via la balise #FILTRE + ## 4.4.21 - 2026-08-20 ### Fixed diff -Nru spip-4.4.21+dfsg/ecrire/action/session.php spip-4.4.23+dfsg/ecrire/action/session.php --- spip-4.4.21+dfsg/ecrire/action/session.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/action/session.php 2026-09-02 11:56:18.000000000 +0000 @@ -32,13 +32,18 @@ **/ function action_session_dist() { if ( - $var = _request('var') - and preg_match(',^[a-z_0-9-]+$,i', $var) + ($cle_autosave = _request('var')) + && preg_match(',^[a-z_0-9-]+$,i', $cle_autosave) ) { if ($_SERVER['REQUEST_METHOD'] == 'POST') { + + $val = _request('val'); + parse_str($val, $vars); + $vars = array_filter($vars, fn($k) => !str_starts_with($k, '_'), ARRAY_FILTER_USE_KEY); + $vars = json_encode($vars); include_spip('inc/session'); - session_set('session_' . $var, $val = _request('val')); - #spip_log("autosave:$var:$val",'autosave'); + session_set('session_' . $cle_autosave, $vars); + #spip_log("autosave:$cle_autosave:$vars",'autosave' . _LOG_DEBUG); } } diff -Nru spip-4.4.21+dfsg/ecrire/balise/formulaire_.php spip-4.4.23+dfsg/ecrire/balise/formulaire_.php --- spip-4.4.21+dfsg/ecrire/balise/formulaire_.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/balise/formulaire_.php 2026-09-02 11:56:18.000000000 +0000 @@ -243,6 +243,10 @@ } // proteger les ' et les " dans les champs que l'on va injecter $valeurs[$champ] = protege_champ($valeurs[$champ]); + } else { + // les champs _xxx permettent d'injecter du html ou du js mais pas plus + include_spip('inc/texte'); + $valeurs[$champ] = interdire_scripts($valeurs[$champ], 1); } } diff -Nru spip-4.4.21+dfsg/ecrire/base/connect_sql.php spip-4.4.23+dfsg/ecrire/base/connect_sql.php --- spip-4.4.21+dfsg/ecrire/base/connect_sql.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/base/connect_sql.php 2026-09-02 11:56:18.000000000 +0000 @@ -89,9 +89,10 @@ if (!isset($GLOBALS['db_ok'])) { spip_log("spip_connect: fichier de connexion '$f' OK mais echec connexion au serveur", _LOG_HS); } - } - else { + } elseif ($serveur !== 'boucle_data') { spip_log("spip_connect: fichier de connexion '$f' non trouve, pas de connexion serveur", _LOG_HS); + } else { + spip_log("spip_connect: boucle DATA, cas toléré, pas de connexion serveur", _LOG_INFO); } if (!isset($GLOBALS['db_ok'])) { // fera mieux la prochaine fois diff -Nru spip-4.4.21+dfsg/ecrire/inc/cvt_autosave.php spip-4.4.23+dfsg/ecrire/inc/cvt_autosave.php --- spip-4.4.21+dfsg/ecrire/inc/cvt_autosave.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/inc/cvt_autosave.php 2026-09-02 11:56:18.000000000 +0000 @@ -26,7 +26,7 @@ * @return string */ function autosave_clean_value($val) { - return stripslashes(urldecode($val)); + return urldecode($val); } /** @@ -53,10 +53,10 @@ if ( isset($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave]) and !$je_suis_poste + and ($vars = json_decode($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave], true)) ) { - parse_str($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave], $vars); foreach ($vars as $key => $val) { - if (isset($flux['data'][$key])) { + if (isset($flux['data'][$key]) && !str_starts_with($key, '_')) { $flux['data'][$key] = (is_string($val) ? autosave_clean_value($val) : array_map( 'autosave_clean_value', $val diff -Nru spip-4.4.21+dfsg/ecrire/inc/modeles.php spip-4.4.23+dfsg/ecrire/inc/modeles.php --- spip-4.4.21+dfsg/ecrire/inc/modeles.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/inc/modeles.php 2026-09-02 11:56:18.000000000 +0000 @@ -38,3 +38,87 @@ ]; return $collecteurModeles->traiter($texte ?? '', $options); } + +/** + * Modèles toujours neutralisés dans un texte public, même s'ils figurent dans l'allowlist. + * + * @return string[] + */ +function modeles_publics_interdits(): array { + return ['formulaire']; +} + +/** + * Liste des modèles autorisés dans un texte soumis ou prévisualisé (contributions publiques, formulaires CVT). + * + * Par défaut vide (aucun modèle). Extension via la constante `_MODELES_PUBLICS_AUTORISES` + * (liste plate ou indexée par contexte) et/ou le pipeline `modeles_publics_autorises`. + * + * @param string $contexte Ex. 'forum', nom de formulaire CVT, plugin… + * @param array{modeles_autorises?: string[]} $options Allowlist explicite (court-circuite constante et pipeline) + * @return string[] + */ +function modeles_publics_autorises(string $contexte = '', array $options = []): array { + if (isset($options['modeles_autorises']) && is_array($options['modeles_autorises'])) { + $modeles = $options['modeles_autorises']; + } else { + $modeles = []; + if (defined('_MODELES_PUBLICS_AUTORISES') && is_array(_MODELES_PUBLICS_AUTORISES)) { + if ($contexte !== '' && isset(_MODELES_PUBLICS_AUTORISES[$contexte]) && is_array(_MODELES_PUBLICS_AUTORISES[$contexte])) { + $modeles = _MODELES_PUBLICS_AUTORISES[$contexte]; + } elseif (array_is_list(_MODELES_PUBLICS_AUTORISES)) { + $modeles = _MODELES_PUBLICS_AUTORISES; + } + } + } + + $data = pipeline('modeles_publics_autorises', [ + 'contexte' => $contexte, + 'modeles' => $modeles, + ]); + + $modeles = is_array($data['modeles'] ?? null) ? $data['modeles'] : []; + + return array_values(array_unique(array_map('strtolower', $modeles))); +} + +/** + * Neutralise les modèles non autorisés dans un texte public. + * + * @param string $contexte + * @param array{modeles_autorises?: string[], remplacer?: string} $options + */ +function neutraliser_modeles_publics(string $texte, string $contexte = '', array $options = []): string { + include_spip('src/Texte/Collecteur/Modeles'); + + $remplacer = $options['remplacer'] ?? '<'; + + if (strlen($texte) > 8000) { + $texte = str_replace('<', $remplacer, $texte); + return $texte; + } + + // pour les modèles interdits on ne laisse rien passer qui ressemble + $interdits = modeles_publics_interdits(); + foreach ($interdits as $interdit) { + $texte = str_ireplace("<{$interdit}", $remplacer . $interdit, $texte); + } + + $autorises = array_flip(array_diff( + modeles_publics_autorises($contexte, $options), + $interdits + )); + + $collecteurModeles = new Spip\Texte\Collecteur\Modeles(); + + return $collecteurModeles->remplacer( + $texte, + function (string $found, array $occurrence) use ($autorises, $remplacer): ?string { + $type = strtolower($occurrence['type'] ?? ''); + if (isset($autorises[$type])) { + return null; + } + return str_replace('<', $remplacer, $found); + } + ); +} diff -Nru spip-4.4.21+dfsg/ecrire/inc/urls.php spip-4.4.23+dfsg/ecrire/inc/urls.php --- spip-4.4.21+dfsg/ecrire/inc/urls.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/inc/urls.php 2026-09-02 11:56:18.000000000 +0000 @@ -141,6 +141,15 @@ if (!defined('_DEFINIR_CONTEXTE_TYPE_PAGE') or _DEFINIR_CONTEXTE_TYPE_PAGE) { $contexte['type-page'] = $type; } + + // Garde-fou : rejeter un type decode erronné (élimination des caractères non \w) + // Note: il y a des cas hors urls_type_objet_valide(). + $validator = fn (?string $value) => $value === null || preg_match(',[^\w\-.],', $value) === 0; + if (!$validator($type) || !$validator($fond)) { + $fond = '404'; + $contexte = ['erreur' => '']; + $url_redirect = ''; // rejete + } } } @@ -242,7 +251,7 @@ */ function urls_liste_objets($preg = true) { static $url_objets = null; - if (is_null($url_objets)) { + if ($url_objets === null) { $url_objets = []; // recuperer les tables_objets_sql declarees $tables_objets = lister_tables_objets_sql(); @@ -262,6 +271,20 @@ } /** + * Indique si un type correspond a un objet URL-able + * + * @param string $type + * @return bool + */ +function urls_type_objet_valide(string $type): bool { + if (!$type || str_contains($type, '/')) { + return false; + } + + return in_array($type, urls_liste_objets(false), true); +} + +/** * Nettoyer une URL, en repérant notamment les raccourcis d'objets * * Repère les entités comme `?article13`, `?rubrique21` ... diff -Nru spip-4.4.21+dfsg/ecrire/inc/utils.php spip-4.4.23+dfsg/ecrire/inc/utils.php --- spip-4.4.21+dfsg/ecrire/inc/utils.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/inc/utils.php 2026-09-02 11:56:18.000000000 +0000 @@ -2196,7 +2196,12 @@ } // note : HTTP_HOST contient le :port si necessaire - if ($host = $_SERVER['HTTP_HOST'] ?? null) { + // si on a la variable $_SERVER['HTTP_HOST_ORIGIN'] set alors HTTP_HOST vient d'un HTTP_X_FORWARDED_HOST d'origine douteuse + // on ne le prends pas en compte pour l'adresse de base du site + if ( + ($host = $_SERVER['HTTP_HOST'] ?? null) + && empty($_SERVER['HTTP_HOST_ORIGIN']) + ) { // Filtrer $host pour proteger d'attaques d'entete HTTP $_SERVER['HTTP_HOST'] = $host = strtr($host, "<>?\"\{\}\$'` \r\n", '____________'); } diff -Nru spip-4.4.21+dfsg/ecrire/inc_version.php spip-4.4.23+dfsg/ecrire/inc_version.php --- spip-4.4.21+dfsg/ecrire/inc_version.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/inc_version.php 2026-09-02 11:56:18.000000000 +0000 @@ -313,8 +313,18 @@ } // securite sur le contenu de l'entete $host = strtr($host, "<>?\"\{\}\$'` \r\n", '____________'); - $_SERVER['HTTP_HOST'] = $host; + // en principe le serveur (Apache ou autre) a deja fait le HTTP_HOST = HTTP_X_FORWARDED_HOST + // et on retrouve donc la même chose + // mais si différents alors il faut affecter + if ($host !== $_SERVER['HTTP_HOST']) { + // si c'est pas un host attendu, on note dans HTTP_HOST_ORIGIN celui qu'on avait initialement + if (!defined('_ALLOWED_FORWARDED_HOST') || !in_array($host, _ALLOWED_FORWARDED_HOST)) { + $_SERVER['HTTP_HOST_ORIGIN'] = $_SERVER['HTTP_HOST']; + } + $_SERVER['HTTP_HOST'] = $host; + } } + // // On note le numero IP du client dans la variable $ip // @@ -451,8 +461,8 @@ // pour specifier les versions de SPIP necessaires // il faut s'en tenir a un nombre de decimales fixe // ex : 2.0.0, 2.0.0-dev, 2.0.0-beta, 2.0.0-beta2 -$spip_version_branche = '4.4.21'; -define('_SPIP_VERSION_ID', 40421); +$spip_version_branche = '4.4.23'; +define('_SPIP_VERSION_ID', 40423); define('_SPIP_EXTRA_VERSION', ''); // cette version dev accepte tous les plugins compatible avec la version ci-dessous @@ -460,7 +470,7 @@ # define('_DEV_VERSION_SPIP_COMPAT', '4.1.99'); // version des signatures de fonctions PHP // (= date de leur derniere modif cassant la compatibilite et/ou necessitant un recalcul des squelettes) -$spip_version_code = 2026_08_17; +$spip_version_code = 2026_09_02; // version de la base SQL (= Date + numero incremental a 2 chiffres YYYYMMDDXX) $spip_version_base = 2026_08_03_00; diff -Nru spip-4.4.21+dfsg/ecrire/paquet.xml spip-4.4.23+dfsg/ecrire/paquet.xml --- spip-4.4.21+dfsg/ecrire/paquet.xml 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/paquet.xml 2026-09-02 11:56:18.000000000 +0000 @@ -1,7 +1,7 @@ + diff -Nru spip-4.4.21+dfsg/ecrire/public/balises.php spip-4.4.23+dfsg/ecrire/public/balises.php --- spip-4.4.21+dfsg/ecrire/public/balises.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/public/balises.php 2026-09-02 11:56:18.000000000 +0000 @@ -1770,10 +1770,9 @@ $args[] = interprete_argument_balise($i + 1, $p); } $p->code = "'<' . '" - . '?php header("X-Spip-Filtre: \'.' - . join('.\'|\'.', $args) - . " . '\"); ?'.'>'"; - + . '?php header("X-Spip-Filtre: \'.signer_filtres_squelettes(' + . implode(').\'|\'.signer_filtres_squelettes(', $args) + . ") . '\"); ?'.'>'"; $p->interdire_scripts = false; return $p; @@ -1895,8 +1894,10 @@ * Pile complétée par le code à générer */ function balise_INSERT_HEAD_dist($p) { + include_spip('public/fonctions'); + $filtre = signer_filtres_squelettes('insert_head_css_conditionnel'); $p->code = "'<'.'" - . '?php header("X-Spip-Filtre: insert_head_css_conditionnel"); ?' + . '?php header("X-Spip-Filtre: ' . $filtre . '"); ?' . "'.'>'"; $p->code .= ". pipeline('insert_head','')"; $p->interdire_scripts = false; diff -Nru spip-4.4.21+dfsg/ecrire/public/cacher.php spip-4.4.23+dfsg/ecrire/public/cacher.php --- spip-4.4.21+dfsg/ecrire/public/cacher.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/public/cacher.php 2026-09-02 11:56:18.000000000 +0000 @@ -167,6 +167,11 @@ function cache_valide(&$page, $date) { $now = $_SERVER['REQUEST_TIME']; + // pas de mise en cache si le contexte contient du $contexte_implicite]; + $page = ['contexte' => $contexte, 'contexte_implicite' => $contexte_implicite]; $use_cache = cache_valide($page, 0); // fichier cache absent : provoque le calcul } diff -Nru spip-4.4.21+dfsg/ecrire/public/compiler.php spip-4.4.23+dfsg/ecrire/public/compiler.php --- spip-4.4.21+dfsg/ecrire/public/compiler.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/public/compiler.php 2026-09-02 11:56:18.000000000 +0000 @@ -160,6 +160,7 @@ /** * Compile une inclusion ou #INCLURE + * @uses safe_export_env() * * @param Inclure $p * Description de l'inclusion (AST au niveau de l'inclure) diff -Nru spip-4.4.21+dfsg/ecrire/public/composer.php spip-4.4.23+dfsg/ecrire/public/composer.php --- spip-4.4.21+dfsg/ecrire/public/composer.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/public/composer.php 2026-09-02 11:56:18.000000000 +0000 @@ -216,6 +216,7 @@ $bloc['innerHtml'], $match ) + && !strlen(trim(str_replace($match[0], '', $bloc['innerHtml']))) ) { # $j = Content-Type, et pas content-TYPE. $j = implode('-', @@ -253,7 +254,7 @@ } $filtres_headers = []; if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) { - $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre'])); + $filtres_headers = verifier_signatures_filtres_squelettes($headers['X-Spip-Filtre']); unset($headers['X-Spip-Filtre']); } if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) { diff -Nru spip-4.4.21+dfsg/ecrire/public/fonctions.php spip-4.4.23+dfsg/ecrire/public/fonctions.php --- spip-4.4.21+dfsg/ecrire/public/fonctions.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/public/fonctions.php 2026-09-02 11:56:18.000000000 +0000 @@ -727,7 +727,7 @@ return $out; } - if (is_string($var) && str_contains($var, '<')) { + if (is_string($var) && strpbrk($var, '<>[]()"\';=\$') !== false) { return 'urldecode(' . var_export(urlencode($var), true) . ')'; } @@ -745,3 +745,69 @@ return ''; } + +/** + * Signer une série de filtres pour la balise #FILTRE + * + * @param string $filtres Chaîne de filtres séparés par des `|` + */ +function signer_filtres_squelettes(string $filtres): string { + $filtres = trim($filtres); + $filtres = explode('|', $filtres); + $filtres = array_map('trim', $filtres); + $filtres = array_filter($filtres); + $nb_filtres = count($filtres); + $filtres = implode('|', $filtres); + if ($nb_filtres > 0) { + if (!function_exists('calculer_cle_action')) { + include_spip('inc/securiser_action'); + } + $hash = calculer_cle_action('filtres:' . $filtres); + $sign = '::sign:' . $nb_filtres . ':' . $hash; + $filtres = $sign . '|' . $filtres; + } + return $filtres; +} + +/** + * Vérifier la signature d'une série de filtres + * + * On ne retient que ceux qui correspondent aux signatures fournies + * Si des filtres ont été ajoutés, ils sont ignorés + * + * @param string $filtres Chaîne de filtres signés par des `|` + * @return string[] Liste de filtres valides + */ +function verifier_signatures_filtres_squelettes(string $filtres): array { + $filtres = explode('|', $filtres); + $filtres = array_filter($filtres); + + // décomposer les séries de filtre signées + $series = []; + $current_serie = ''; + $nb_current_serie = 0; + foreach ($filtres as $filtre) { + if (str_starts_with($filtre, '::sign:')) { + $nb_current_serie = intval(substr($filtre, strlen('::sign:'))); + $current_serie = $filtre; + $series[$current_serie] = ''; + } elseif ($current_serie && $nb_current_serie > 0) { + $series[$current_serie] .= "|$filtre"; + $nb_current_serie--; + } + } + + // verifier la signature de chaque série + $filtres = []; + foreach ($series as $sign_header => $serie) { + if (strlen($serie)) { + $check = signer_filtres_squelettes($serie); + if ($check === $sign_header . $serie) { + $filtres[] = substr($serie, 1); + } + } + } + $filtres = implode('|', $filtres); + $filtres = explode('|', $filtres); + return $filtres; +} diff -Nru spip-4.4.21+dfsg/ecrire/public/sandbox.php spip-4.4.23+dfsg/ecrire/public/sandbox.php --- spip-4.4.21+dfsg/ecrire/public/sandbox.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/public/sandbox.php 2026-09-02 11:56:18.000000000 +0000 @@ -108,7 +108,13 @@ * } */ function analyser_arguments_filtre(string $function): array { - $refl = strpbrk((string) $function, ':') ? new ReflectionMethod($function) : new ReflectionFunction($function); + if (strpbrk($function, ':')) { + $refl = PHP_VERSION_ID >= 80300 + ? ReflectionMethod::createFromMethodName($function) + : new ReflectionMethod($function); + } else { + $refl = new ReflectionFunction($function); + } $refs = $refl->getParameters(); return [ 'Pile' => isset($refs[0]) && $refs[0]->name == 'Pile', diff -Nru spip-4.4.21+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php spip-4.4.23+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php --- spip-4.4.21+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php 2026-08-20 11:41:28.000000000 +0000 +++ spip-4.4.23+dfsg/ecrire/src/Texte/Collecteur/AbstractCollecteur.php 2026-09-02 11:56:18.000000000 +0000 @@ -133,24 +133,27 @@ while ( ($ifchars_last_pos === null || $pos <= $ifchars_last_pos) && ($next = ($start_with ? strpos($texte, $start_with, $pos) : $pos)) !== false - && preg_match($preg, $texte, $r, PREG_OFFSET_CAPTURE, $next) ) { - $found_pos = $r[0][1]; - $found_length = strlen($r[0][0]); - $match = [ - 'raw' => $r[0][0], - 'match' => array_column($r, 0), - 'pos' => $found_pos, - 'length' => $found_length, - ]; + if (preg_match($preg, $texte, $r, PREG_OFFSET_CAPTURE, $next)) { + $found_pos = $r[0][1]; + $found_length = strlen($r[0][0]); + $match = [ + 'raw' => $r[0][0], + 'match' => array_column($r, 0), + 'pos' => $found_pos, + 'length' => $found_length, + ]; - $collection[] = $match; + $collection[] = $match; - if ($max_items && count($collection) === $max_items) { - break; - } + if ($max_items && count($collection) === $max_items) { + break; + } - $pos = $match['pos'] + $match['length']; + $pos = $match['pos'] + $match['length']; + } else { + $pos = $next + 1; // continuer le reste du texte même si la preg a echoué + } } } diff -Nru spip-4.4.21+dfsg/plugins-dist/bigup/CHANGELOG.md spip-4.4.23+dfsg/plugins-dist/bigup/CHANGELOG.md --- spip-4.4.21+dfsg/plugins-dist/bigup/CHANGELOG.md 2026-08-20 11:47:00.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/bigup/CHANGELOG.md 2026-09-02 12:02:52.000000000 +0000 @@ -1,5 +1,11 @@ # Changelog +## 3.3.14 - 2026-09-02 + +### Security + +- spip-security/securite#4911 Autorisation sur formulaire de test de bigup + ## 3.3.13 - 2026-08-17 ### Fixed diff -Nru spip-4.4.21+dfsg/plugins-dist/bigup/formulaires/tester_bigup.php spip-4.4.23+dfsg/plugins-dist/bigup/formulaires/tester_bigup.php --- spip-4.4.21+dfsg/plugins-dist/bigup/formulaires/tester_bigup.php 2026-08-20 11:47:00.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/bigup/formulaires/tester_bigup.php 2026-09-02 12:02:52.000000000 +0000 @@ -19,6 +19,11 @@ */ function formulaires_tester_bigup_charger_dist($id = 0) { + include_spip('inc/autoriser'); + if (!autoriser('configurer', '_bigup')) { + return false; + } + $valeurs = [ 'titre' => '', ]; diff -Nru spip-4.4.21+dfsg/plugins-dist/bigup/formulaires/tester_bigup_extended.php spip-4.4.23+dfsg/plugins-dist/bigup/formulaires/tester_bigup_extended.php --- spip-4.4.21+dfsg/plugins-dist/bigup/formulaires/tester_bigup_extended.php 2026-08-20 11:47:00.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/bigup/formulaires/tester_bigup_extended.php 2026-09-02 12:02:52.000000000 +0000 @@ -8,6 +8,10 @@ */ function formulaires_tester_bigup_extended_charger_dist($id = 0, $target = '', $bloc = '') { + include_spip('inc/autoriser'); + if (!autoriser('configurer', '_bigup')) { + return false; + } $valeurs = [ '_id' => 'form_tester_bigup_extended_' . $id, diff -Nru spip-4.4.21+dfsg/plugins-dist/bigup/paquet.xml spip-4.4.23+dfsg/plugins-dist/bigup/paquet.xml --- spip-4.4.21+dfsg/plugins-dist/bigup/paquet.xml 2026-08-20 11:47:00.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/bigup/paquet.xml 2026-09-02 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ '; return $flux; diff -Nru spip-4.4.21+dfsg/plugins-dist/compresseur/paquet.xml spip-4.4.23+dfsg/plugins-dist/compresseur/paquet.xml --- spip-4.4.21+dfsg/plugins-dist/compresseur/paquet.xml 2026-08-20 11:47:00.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/compresseur/paquet.xml 2026-09-02 12:02:54.000000000 +0000 @@ -1,7 +1,7 @@ ` sur le contenu de la prévisu +- spip-security/securite#4907 longueur maxi par défaut des messages de forum +- spip-security/securite#4912 une autorisation sur les forums prives + securiser la prévisu comme sur les forums publics + +## 3.1.16 - 2026-09-01 + +### Security + +- spip-security/securite#4902 Appliquer strip_tags sur nom_site qui n'attends aucun html +- spip-security/securite#4902 Appliquer les traitements forums (#TEXTE, #TITRE, #NOM_SITE, #URL_SITE) à la prévisualisation + +### Fixed + +- Échapper + nettoyer les modeles en 2 fois pour ne pas abimer le contenu des blocs code/backticks + ## 3.1.15 - 2026-08-10 ### Fixed diff -Nru spip-4.4.21+dfsg/plugins-dist/forum/base/forum.php spip-4.4.23+dfsg/plugins-dist/forum/base/forum.php --- spip-4.4.21+dfsg/plugins-dist/forum/base/forum.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/forum/base/forum.php 2026-09-02 12:02:54.000000000 +0000 @@ -52,26 +52,26 @@ ]; $interfaces['table_des_traitements']['PARAMETRES_FORUM'][] = 'spip_htmlspecialchars(%s)'; - $interfaces['table_des_traitements']['TEXTE']['forums'] = 'liens_nofollow(safehtml(' . str_replace( + $interfaces['table_des_traitements']['TEXTE']['forums'] = 'liens_nofollow(safehtml(interdit_html_nettoyer(' . str_replace( '%s', 'interdit_html(%s)', _TRAITEMENT_RACCOURCIS - ) . '))'; - $interfaces['table_des_traitements']['TITRE']['forums'] = 'liens_nofollow(safehtml(' . str_replace( + ) . ')))'; + $interfaces['table_des_traitements']['TITRE']['forums'] = 'liens_nofollow(safehtml(interdit_html_nettoyer(' . str_replace( '%s', 'interdit_html(%s)', _TRAITEMENT_TYPO - ) . '))'; - $interfaces['table_des_traitements']['NOTES']['forums'] = 'liens_nofollow(safehtml(' . str_replace( + ) . ')))'; + $interfaces['table_des_traitements']['NOTES']['forums'] = 'liens_nofollow(safehtml(interdit_html_nettoyer(' . str_replace( '%s', 'interdit_html(%s)', _TRAITEMENT_RACCOURCIS - ) . '))'; - $interfaces['table_des_traitements']['NOM_SITE']['forums'] = 'liens_nofollow(safehtml(' . str_replace( + ) . ')))'; + $interfaces['table_des_traitements']['NOM_SITE']['forums'] = 'liens_nofollow(safehtml(interdit_html_nettoyer(' . str_replace( '%s', 'interdit_html(%s)', _TRAITEMENT_TYPO - ) . '))'; + ) . ')))'; $interfaces['table_des_traitements']['URL_SITE']['forums'] = 'safehtml(vider_url(%s))'; $interfaces['table_des_traitements']['AUTEUR']['forums'] = 'liens_nofollow(safehtml(vider_url(%s)))'; $interfaces['table_des_traitements']['EMAIL_AUTEUR']['forums'] = 'safehtml(vider_url(%s))'; diff -Nru spip-4.4.21+dfsg/plugins-dist/forum/formulaires/forum.php spip-4.4.23+dfsg/plugins-dist/forum/formulaires/forum.php --- spip-4.4.21+dfsg/plugins-dist/forum/formulaires/forum.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/forum/formulaires/forum.php 2026-09-02 12:02:54.000000000 +0000 @@ -312,6 +312,7 @@ } $min_length = (defined('_FORUM_LONGUEUR_MINI') ? _FORUM_LONGUEUR_MINI : 10); + $max_length = (defined('_FORUM_LONGUEUR_MAXI') ? _FORUM_LONGUEUR_MAXI : 8000); if ( strlen($texte = _request('texte')) < $min_length and !$ajouter_mot and $GLOBALS['meta']['forums_texte'] == 'oui' @@ -321,15 +322,14 @@ ['min' => $min_length] ); } elseif ( - defined('_FORUM_LONGUEUR_MAXI') - and _FORUM_LONGUEUR_MAXI > 0 - and strlen($texte) > _FORUM_LONGUEUR_MAXI + $max_length > 0 + && strlen($texte) > $max_length ) { $erreurs['texte'] = _T( 'forum:forum_attention_trop_caracteres', [ 'compte' => strlen($texte), - 'max' => _FORUM_LONGUEUR_MAXI, + 'max' => $max_length, ] ); } @@ -360,6 +360,11 @@ $erreurs['titre'] = _T('forum:forum_attention_trois_caracteres'); } + // on strip_tags sur nom_site + if ($nom_site = _request('nom_site')) { + set_request('nom_site', strip_tags($nom_site)); + } + if (!count($erreurs) and !_request('confirmer_previsu_forum')) { if (!_request('envoyer_message') or $forcer_previsu != 'non') { $previsu = inclure_previsu( @@ -438,42 +443,30 @@ $id_objet, $id_forum ) { - global $table_des_traitements; - $bouton = _T('forum:forum_message_definitif'); include_spip('public/assembler'); include_spip('public/composer'); - - // appliquer les traitements de #TEXTE a la previsu - // comme on voit c'est complique... y a peut-etre plus simple ? - // recuperer les filtres eventuels de 'mes_fonctions.php' sur les balises include_spip('public/parametrer'); - $tmptexte = ''; - $evaltexte = $table_des_traitements['TEXTE']['forums'] ?? $table_des_traitements['TEXTE'][0]; - $evaltexte = '$tmptexte = ' . str_replace('%s', '$texte', $evaltexte) . ';'; - // evaluer... - // [fixme] - // $connect et $Pile ne sont pas definis ici :/ - // mais font souvent partie des variables appelees par les traitements - $connect = ''; - $Pile = [0 => []]; - eval($evaltexte); + + // appliquer les traitements forums (#TEXTE, #TITRE, #NOM_SITE) a la previsu + $texte = appliquer_traitement_champ($texte, 'TEXTE', 'forums'); + $titre = appliquer_traitement_champ($titre, 'TITRE', 'forums'); + $nom_site = appliquer_traitement_champ($nom_site, 'NOM_SITE', 'forums'); + $url_site = appliquer_traitement_champ($nom_site, 'URL_SITE', 'forums'); // supprimer les
de la previsualisation // (sinon on ne peut pas faire ... dans les forums) - return preg_replace( - "@<(/?)form\b@ism", - '<\1div', + return forum_previsu_nettoyer_forms( inclure_balise_dynamique( [ 'formulaires/inc-forum_previsu', 0, [ - 'titre' => safehtml(typo($titre)), - 'texte' => $tmptexte, + 'titre' => $titre, + 'texte' => $texte, 'notes' => safehtml(calculer_notes()), - 'url_site' => vider_url($url_site), - 'nom_site' => safehtml(typo($nom_site)), + 'url_site' => $url_site, + 'nom_site' => $nom_site, 'ajouter_mot' => (is_array($ajouter_mot) ? $ajouter_mot : [$ajouter_mot]), 'ajouter_document' => $doc, # 'erreur' => $erreur, // non definie ? diff -Nru spip-4.4.21+dfsg/plugins-dist/forum/formulaires/forum_prive.php spip-4.4.23+dfsg/plugins-dist/forum/formulaires/forum_prive.php --- spip-4.4.21+dfsg/plugins-dist/forum/formulaires/forum_prive.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/forum/formulaires/forum_prive.php 2026-09-02 12:02:54.000000000 +0000 @@ -26,6 +26,11 @@ function formulaires_forum_prive_charger_dist($objet, $id_objet, $id_forum, $forcer_previsu, $statut, $retour = '') { + include_spip('inc/autoriser'); + if (!autoriser('participerforumprive', $objet, $id_objet)) { + return false; + } + if (!function_exists($f = 'forum_recuperer_titre')) { $f = 'forum_recuperer_titre_dist'; } @@ -92,6 +97,7 @@ $erreurs = []; $min_length = (defined('_FORUM_LONGUEUR_MINI') ? _FORUM_LONGUEUR_MINI : 10); + $max_length = (defined('_FORUM_LONGUEUR_MAXI') ? _FORUM_LONGUEUR_MAXI : 8000); if ( strlen($texte = _request('texte')) < $min_length and !_request('ajouter_mot') and $GLOBALS['meta']['forums_texte'] == 'oui' @@ -102,15 +108,14 @@ ); } else { if ( - defined('_FORUM_LONGUEUR_MAXI') - and _FORUM_LONGUEUR_MAXI > 0 - and strlen($texte) > _FORUM_LONGUEUR_MAXI + $max_length > 0 + && strlen($texte) > $max_length ) { $erreurs['texte'] = _T( 'forum:forum_attention_trop_caracteres', [ 'compte' => strlen($texte), - 'max' => _FORUM_LONGUEUR_MAXI, + 'max' => $max_length, ] ); } @@ -150,21 +155,27 @@ $bouton = _T('forum:forum_message_definitif'); include_spip('public/assembler'); include_spip('public/composer'); + include_spip('public/parametrer'); + + // appliquer les traitements forums (#TEXTE, #TITRE, #NOM_SITE) a la previsu + $texte = appliquer_traitement_champ($texte, 'TEXTE', 'forums'); + $titre = appliquer_traitement_champ($titre, 'TITRE', 'forums'); + $nom_site = appliquer_traitement_champ($nom_site, 'NOM_SITE', 'forums'); + $url_site = appliquer_traitement_champ($nom_site, 'URL_SITE', 'forums'); + // supprimer les de la previsualisation // (sinon on ne peut pas faire ... dans les forums) - return preg_replace( - "@<(/?)form\b@ism", - '<\1div', + return forum_previsu_nettoyer_forms( inclure_balise_dynamique( [ 'formulaires/inc-forum_prive_previsu', 0, [ - 'titre' => safehtml(typo($titre)), - 'texte' => safehtml(propre($texte)), + 'titre' => $titre, + 'texte' => $texte, 'notes' => safehtml(calculer_notes()), - 'url_site' => vider_url($url_site), - 'nom_site' => safehtml(typo($nom_site)), + 'url_site' => $url_site, + 'nom_site' => $nom_site, 'ajouter_mot' => (is_array($ajouter_mot) ? $ajouter_mot : [$ajouter_mot]), 'ajouter_document' => $doc, # 'erreur' => $erreur, // kesako ? non définie ? diff -Nru spip-4.4.21+dfsg/plugins-dist/forum/forum_autoriser.php spip-4.4.23+dfsg/plugins-dist/forum/forum_autoriser.php --- spip-4.4.21+dfsg/plugins-dist/forum/forum_autoriser.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/forum/forum_autoriser.php 2026-09-02 12:02:54.000000000 +0000 @@ -233,7 +233,7 @@ /** * Autorisation de participer au forum privé d'un objet quelconque * - * Afin de rester compatible avec l'existant cette autorisation est toujours vraie. + * Afin de rester compatible avec l'existant cette autorisation est toujours vraie pour ceux qui ont accès à ecrire * * @param string $faire Action demandée * @param string $type Type d'objet sur lequel appliquer l'action @@ -243,7 +243,7 @@ * @return bool true s'il a le droit, false sinon */ function autoriser_participerforumprive_dist($faire, $type, $id, $qui, $opt) { - return true; + return autoriser('ecrire', '', 0, $qui, $opt); } /** diff -Nru spip-4.4.21+dfsg/plugins-dist/forum/forum_fonctions.php spip-4.4.23+dfsg/plugins-dist/forum/forum_fonctions.php --- spip-4.4.21+dfsg/plugins-dist/forum/forum_fonctions.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/forum/forum_fonctions.php 2026-09-02 12:02:54.000000000 +0000 @@ -9,14 +9,14 @@ * Ce programme est un logiciel libre distribué sous licence GNU/GPL. */ -use Spip\Texte\Collecteur\Modeles as CollecteurModeles; - /** * Définit les fonctions utiles du plugin forum * * @package SPIP\Forum\Fonctions */ +use Spip\Texte\Collecteur\HtmlTag as CollecteurHtmlTag; + if (!defined('_ECRIRE_INC_VERSION')) { return; } @@ -76,13 +76,14 @@ } /** - * Désactive les modèles dans un texte + * Neutralise les modèles non autorisés dans un texte de forum. + * + * @deprecated 4.4 Utiliser neutraliser_modeles_publics($texte, 'forum') */ function forum_desactiver_modeles(string $texte): string { - return (new CollecteurModeles())->remplacer( - $texte, - fn (string $found) => str_replace('<', '<', $found) - ); + trigger_deprecation('spip/forum', '4.4', 'Using "%s" is deprecated, use "%s" instead', __FUNCTION__, 'neutraliser_modeles_publics'); + + return neutraliser_modeles_publics($texte, 'forum'); } /** @@ -98,15 +99,60 @@ * @param string $texte */ function interdit_html($texte): string { - - $texte ??= ''; - if (!defined('_FORUM_INTERDIRE_MODELES') || _FORUM_INTERDIRE_MODELES) { - $texte = forum_desactiver_modeles($texte); + if (!$texte) { + return $texte; } + // si html interdit, tous les < sont neutralisés, pas la peine de faire de la dentelle avec les modèles if (defined('_INTERDIRE_TEXTE_HTML')) { $texte = str_replace('<', '<', $texte); + } else { + // enlever tout ZERO WIDTH SPACE qui aurait été dans l'entrée initiale + if (str_contains($texte, "\u{200b}")) { + $texte = str_replace("\u{200b}", '', $texte); + } + include_spip('inc/modeles'); + // on insère un U+200B ZERO WIDTH SPACE derrière le < pour désactiver la détection des modèles + $texte = neutraliser_modeles_publics($texte ??= '', 'forum', ['remplacer' => "<\u{200b}"]); + } + + return $texte; +} + +function interdit_html_nettoyer($texte): string { + if ($texte && str_contains($texte, "\u{200b}")) { + $texte = str_replace(["<\u{200b}", "\u{200b}"], ['<', ''], $texte); + } + return $texte; +} + +/** + * Nettoyer les balises et leurs input hidden dans la previsu + */ +function forum_previsu_nettoyer_forms(string $texte): string { + if (!$texte) { + return $texte; } + // si l'interprétation du message a produit un formulaire, on nettoie les balises + // et les balises + include_spip('inc/filtres'); + $collecteurForm = new CollecteurHtmlTag('form'); + $texte = $collecteurForm->remplacer($texte, function ($form, $bloc) { + $opening = 'remplacer($inner, function ($input) { + if (extraire_attribut($input, 'type') === 'hidden') { + return ''; + } + return null; + }); + } + return $opening . $inner . ''; + }); return $texte; } diff -Nru spip-4.4.21+dfsg/plugins-dist/forum/paquet.xml spip-4.4.23+dfsg/plugins-dist/forum/paquet.xml --- spip-4.4.21+dfsg/plugins-dist/forum/paquet.xml 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/forum/paquet.xml 2026-09-02 12:02:54.000000000 +0000 @@ -1,7 +1,7 @@ _T('info_acces_interdit')]; + } + include_spip('inc/joindre_document'); $erreurs = []; @@ -295,6 +323,10 @@ $proposer_media = true, $proposer_ftp = true ) { + if (!joindre_document_est_autorise($id_document, $id_objet, $objet)) { + return ['editable' => false, 'message_erreur' => _T('info_acces_interdit')]; + } + $res = ['editable' => true]; $ancre = ''; // on joint un document deja dans le site diff -Nru spip-4.4.21+dfsg/plugins-dist/medias/inc/documents.php spip-4.4.23+dfsg/plugins-dist/medias/inc/documents.php --- spip-4.4.21+dfsg/plugins-dist/medias/inc/documents.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/medias/inc/documents.php 2026-09-02 12:02:56.000000000 +0000 @@ -113,9 +113,7 @@ include_spip('inc/distant'); include_spip('inc/texte'); include_spip('inc/filtres_images_mini'); - if ($class === null) { - $class = 'spip_logo spip_logos'; - } + $class ??= 'spip_logo spip_logos'; $e = $doc['extension'] ?? null; if (!$img) { if ($img = image_du_document($doc, $connect)) { diff -Nru spip-4.4.21+dfsg/plugins-dist/medias/medias_autoriser.php spip-4.4.23+dfsg/plugins-dist/medias/medias_autoriser.php --- spip-4.4.21+dfsg/plugins-dist/medias/medias_autoriser.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/medias/medias_autoriser.php 2026-09-02 12:02:56.000000000 +0000 @@ -138,11 +138,15 @@ return autoriser('modifier', $type, $id, $qui, $opt); } // sur un nouvel objet if ($id < 0 and (abs($id) == $qui['id_auteur'])) { - return autoriser('ecrire', $type, $id, $qui, $opt); + return autoriser('creer', $type, 0, $qui, $opt); } + } elseif (!empty($type)) { + // si type fourni mais pas dans la liste autorisée par documents_objets, c'est niet + return false; } - return false; + // si pas de type fourni ou id=0 alors il faut avoir le droit de créer des contenus (0minirezo ou 1comite par defaut) + return autoriser('creer', 'document', 0, $qui, $opt); } /** diff -Nru spip-4.4.21+dfsg/plugins-dist/medias/paquet.xml spip-4.4.23+dfsg/plugins-dist/medias/paquet.xml --- spip-4.4.21+dfsg/plugins-dist/medias/paquet.xml 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/medias/paquet.xml 2026-09-02 12:02:56.000000000 +0000 @@ -1,6 +1,6 @@ - +
[(#GET{editable}) @@ -71,4 +71,4 @@ ] -] +] \ No newline at end of file diff -Nru spip-4.4.21+dfsg/plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation_fonctions.php spip-4.4.23+dfsg/plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation_fonctions.php --- spip-4.4.21+dfsg/plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation_fonctions.php 2026-08-20 11:47:02.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/medias/prive/squelettes/inclure/mediatheque-navigation_fonctions.php 2026-09-02 12:02:56.000000000 +0000 @@ -42,3 +42,14 @@ 'media_defaut' ); } + +function medias_verifier_galerie($fond, $sinon) { + if (empty($fond)) { + return $sinon; + } + $base = basename($fond); + if (!preg_match(",^mediatheque-[\w-]+$,", $base)) { + return $sinon; + } + return dirname($sinon) . '/' . $base; +} diff -Nru spip-4.4.21+dfsg/plugins-dist/textwheel/CHANGELOG.md spip-4.4.23+dfsg/plugins-dist/textwheel/CHANGELOG.md --- spip-4.4.21+dfsg/plugins-dist/textwheel/CHANGELOG.md 2026-08-20 11:47:04.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/textwheel/CHANGELOG.md 2026-09-02 12:02:58.000000000 +0000 @@ -1,5 +1,11 @@ # Changelog +## 3.3.11 - 2026-09-01 + +### Fixed + +- #4895 ne pas traiter le raccourci cadre/frame dans les traitements typo + ## 3.3.10 - 2026-08-10 ### Fixed diff -Nru spip-4.4.21+dfsg/plugins-dist/textwheel/inc/texte.php spip-4.4.23+dfsg/plugins-dist/textwheel/inc/texte.php --- spip-4.4.21+dfsg/plugins-dist/textwheel/inc/texte.php 2026-08-20 11:47:04.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/textwheel/inc/texte.php 2026-09-02 12:02:58.000000000 +0000 @@ -251,6 +251,8 @@ 'connect' => $connect, 'env' => $env, ]; + // les cadre et frame restent non traités par typo() + $letexte = echappe_html($letexte, $echapper, true, '@]*?)(/?)>@isS'); $letexte = echappe_html($letexte, $echapper, false, null, '', $callback_options); } diff -Nru spip-4.4.21+dfsg/plugins-dist/textwheel/paquet.xml spip-4.4.23+dfsg/plugins-dist/textwheel/paquet.xml --- spip-4.4.21+dfsg/plugins-dist/textwheel/paquet.xml 2026-08-20 11:47:04.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/textwheel/paquet.xml 2026-09-02 12:02:58.000000000 +0000 @@ -1,6 +1,6 @@ $id, ]; + if (!editer_url_objet_est_autorise($type, $id)) { + return false; + } + return $valeurs; } @@ -39,6 +59,10 @@ * @return array */ function formulaires_editer_url_objet_verifier_dist($type, $id) { + if (!editer_url_objet_est_autorise($type, $id)) { + return ['message_erreur' => _T('info_acces_interdit')]; + } + $url_clean = []; $erreurs = []; include_spip('action/editer_url'); @@ -86,6 +110,10 @@ * @return array */ function formulaires_editer_url_objet_traiter_dist($type, $id) { + if (!editer_url_objet_est_autorise($type, $id)) { + return ['editable' => false, 'message_erreur' => _T('info_acces_interdit')]; + } + $valeurs = ['editable' => true]; include_spip('action/editer_url'); diff -Nru spip-4.4.21+dfsg/plugins-dist/urls_etendues/paquet.xml spip-4.4.23+dfsg/plugins-dist/urls_etendues/paquet.xml --- spip-4.4.21+dfsg/plugins-dist/urls_etendues/paquet.xml 2026-08-20 11:47:06.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/urls_etendues/paquet.xml 2026-09-02 12:02:58.000000000 +0000 @@ -1,6 +1,6 @@ <:bouton_modifier:>] [(#GET{auth}|non)] (#ID_OBJET|generer_objet_url{#OBJET,'','',#EVAL{true}}|url_absolue)[(#GET{auth}|?{,})]] - [(#AUTORISER{modifier,#OBJET,#ID_OBJET}) + [(#GET{auth}|oui)
#FORMULAIRE_EDITER_URL_OBJET{#OBJET,#ID_OBJET} diff -Nru spip-4.4.21+dfsg/plugins-dist/urls_etendues/urls/arbo.php spip-4.4.23+dfsg/plugins-dist/urls_etendues/urls/arbo.php --- spip-4.4.21+dfsg/plugins-dist/urls_etendues/urls/arbo.php 2026-08-20 11:47:06.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/urls_etendues/urls/arbo.php 2026-09-02 12:02:58.000000000 +0000 @@ -162,11 +162,7 @@ function url_arbo_terminaison(string $type): string { $terminaison_types = url_arbo_terminaisons_par_type(); - if (isset($terminaison_types[$type])) { - return $terminaison_types[$type]; - } - - return $terminaison_types['defaut'] ?? ''; + return $terminaison_types[$type] ?? $terminaison_types['defaut'] ?? ''; } /** diff -Nru spip-4.4.21+dfsg/plugins-dist/urls_etendues/urls_autoriser.php spip-4.4.23+dfsg/plugins-dist/urls_etendues/urls_autoriser.php --- spip-4.4.21+dfsg/plugins-dist/urls_etendues/urls_autoriser.php 2026-08-20 11:47:06.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/urls_etendues/urls_autoriser.php 2026-09-02 12:02:58.000000000 +0000 @@ -76,6 +76,11 @@ /** * Autorisation de modifier l'url d'un objet * + * - visiteur anonyme : toujours refuse + * - objet publie (ou equivalent en ligne) : reserve aux admins complets (0minirezo non restreint) + * - sinon : delegation a autoriser('modifier', …) + * - objet disparu : fallback sur autoriser('administrer', 'url') + * * @param string $faire Action demandée * @param string $type Type d'objet sur lequel appliquer l'action * @param int $id Identifiant de l'objet @@ -84,14 +89,26 @@ * @return bool true s'il a le droit, false sinon */ function autoriser_modifierurl_dist($faire, $type = '', $id = 0, $qui = null, $opt = null) { + // anonyme : jamais le droit de modifier une URL + if (!$qui['id_auteur'] || !$qui['statut']) { + return false; + } + + if (!$type || !intval($id)) { + return false; + } + + // objet publie (ou equivalent en ligne) : reserve aux admins complets + include_spip('base/objets'); + if (objet_test_si_publie($type, $id)) { + return $qui['statut'] === '0minirezo' && !$qui['restreint']; + } + if (autoriser('modifier', $type, $id, $qui, $opt)) { return true; } // si pas le droit de 'modifier', regarder d'un peu plus pres pourquoi - if (!$type or !intval($id)) { - return false; - } // verifier si l'objet existe encore en base $table_sql = table_objet_sql($type); $primary = id_table_objet($type); diff -Nru spip-4.4.21+dfsg/plugins-dist/urls_etendues/urls_fonctions.php spip-4.4.23+dfsg/plugins-dist/urls_etendues/urls_fonctions.php --- spip-4.4.21+dfsg/plugins-dist/urls_etendues/urls_fonctions.php 2026-08-20 11:47:06.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist/urls_etendues/urls_fonctions.php 2026-09-02 12:02:58.000000000 +0000 @@ -20,8 +20,9 @@ */ function urls_is_url_editable(?string $objet, $id_objet, string $serveur = ''): bool { include_spip('base/objets'); + include_spip('inc/urls'); - if (!$objet or !$id_objet) { + if (!$objet || !$id_objet || !urls_type_objet_valide($objet)) { return false; } diff -Nru spip-4.4.21+dfsg/plugins-dist.json spip-4.4.23+dfsg/plugins-dist.json --- spip-4.4.21+dfsg/plugins-dist.json 2026-08-20 11:46:58.000000000 +0000 +++ spip-4.4.23+dfsg/plugins-dist.json 2026-09-02 12:02:52.000000000 +0000 @@ -15,7 +15,7 @@ "path": "plugins-dist/bigup", "source": "https://git.spip.net/spip/bigup.git", "branch": "3.x", - "tag": "3.3.13" + "tag": "3.3.14" }, "compagnon": { "path": "plugins-dist/compagnon", @@ -27,7 +27,7 @@ "path": "plugins-dist/compresseur", "source": "https://git.spip.net/spip/compresseur.git", "branch": "2.x", - "tag": "2.2.4" + "tag": "2.2.5" }, "dump": { "path": "plugins-dist/dump", @@ -39,13 +39,13 @@ "path": "plugins-dist/filtres_images", "source": "https://git.spip.net/spip/images.git", "branch": "4.x", - "tag": "4.3.11" + "tag": "4.3.12" }, "forum": { "path": "plugins-dist/forum", "source": "https://git.spip.net/spip/forum.git", "branch": "3.x", - "tag": "3.1.15" + "tag": "3.1.17" }, "mediabox": { "path": "plugins-dist/mediabox", @@ -57,7 +57,7 @@ "path": "plugins-dist/medias", "source": "https://git.spip.net/spip/medias.git", "branch": "4.x", - "tag": "4.4.11" + "tag": "4.4.13" }, "mots": { "path": "plugins-dist/mots", @@ -111,12 +111,12 @@ "path": "plugins-dist/textwheel", "source": "https://git.spip.net/spip/tw.git", "branch": "3.x", - "tag": "3.3.10" + "tag": "3.3.11" }, "urls_etendues": { "path": "plugins-dist/urls_etendues", "source": "https://git.spip.net/spip/urls.git", "branch": "4.x", - "tag": "4.2.3" + "tag": "4.2.4" } } \ No newline at end of file diff -Nru spip-4.4.21+dfsg/prive/CHANGELOG.md spip-4.4.23+dfsg/prive/CHANGELOG.md --- spip-4.4.21+dfsg/prive/CHANGELOG.md 2026-08-12 09:11:36.000000000 +0000 +++ spip-4.4.23+dfsg/prive/CHANGELOG.md 2026-09-02 11:45:16.000000000 +0000 @@ -5,6 +5,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.1.5 - 2026-09-02 + +### Security + +- spip-security/securite#4909 la modification d'un mot de passe via id_auteur necessite une autorisation + +## 1.1.4 - 2026-09-01 + +### Security + +- spip-security/securite#4901 les url de reset on un token qui n'est valide que pour le host de l'URL + +### Fixed + +- #140 corrections UI sur petit écran (sur liste de liaisons comme auteurs ou mots clés) + ## 1.1.3 - 2026-08-12 ### Fixed diff -Nru spip-4.4.21+dfsg/prive/formulaires/mot_de_passe.php spip-4.4.23+dfsg/prive/formulaires/mot_de_passe.php --- spip-4.4.21+dfsg/prive/formulaires/mot_de_passe.php 2026-08-12 09:11:36.000000000 +0000 +++ spip-4.4.23+dfsg/prive/formulaires/mot_de_passe.php 2026-09-02 11:45:16.000000000 +0000 @@ -26,7 +26,15 @@ ); } elseif ($jeton) { include_spip('action/inscrire_auteur'); - if ($auteur = auteur_verifier_jeton($jeton) + // on supporte un appel avec le jeton en clair, au cas ou quelqu'un aurait surchargé le formulaire oubli + // mais en principe le jeton a été hashé avec le HOST, il faut donc le de-hasher + $host = parse_url(url_de_base(), PHP_URL_HOST); + include_spip('inc/securiser_action'); + $key_host = pack('H*', calculer_cle_action($host)); + $jeton_by_host = pack('H*', $jeton); + $jeton_by_host = _xor($jeton_by_host, $key_host); + if ( + ($auteur = auteur_verifier_jeton($jeton) or $auteur = auteur_verifier_jeton($jeton_by_host)) and $auteur['statut'] <> '5poubelle' and $auteur['pass'] <> '' and $auteur['login'] <> '' @@ -46,10 +54,17 @@ * Dans les deux cas on verifie que l'auteur est autorise * * @param int $id_auteur - * @return array + * @return false|array */ function formulaires_mot_de_passe_charger_dist($id_auteur = null, $jeton = null) { + if ($id_auteur) { + include_spip('inc/autoriser'); + if (!autoriser('modifier', 'auteur', $id_auteur, null, ['pass' => '?'])) { + return false; + } + } + $valeurs = array(); // compatibilite anciens appels du formulaire if (is_null($jeton)) { diff -Nru spip-4.4.21+dfsg/prive/formulaires/oubli.php spip-4.4.23+dfsg/prive/formulaires/oubli.php --- spip-4.4.21+dfsg/prive/formulaires/oubli.php 2026-08-12 09:11:36.000000000 +0000 +++ spip-4.4.23+dfsg/prive/formulaires/oubli.php 2026-09-02 11:45:16.000000000 +0000 @@ -30,11 +30,22 @@ include_spip('action/inscrire_auteur'); $token = auteur_attribuer_jeton($r[1]['id_auteur']); + $url_reset = generer_url_public('spip_pass', '', false, false); + $host = parse_url($url_reset, PHP_URL_HOST); + + include_spip('inc/securiser_action'); + $key_host = pack('H*', calculer_cle_action($host)); + $token_by_host = _xor($token, $key_host); + $token_by_host = unpack('H*', $token_by_host); + $token_by_host = reset($token_by_host); + + $url_reset = parametre_url($url_reset, 'p', $token_by_host); + include_spip('inc/filtres'); $msg = recuperer_fond( 'modeles/mail_oubli', [ - 'url_reset' => generer_url_public('spip_pass', "p=$token", false, false) + 'url_reset' => $url_reset, ] ); include_spip('inc/notifications'); diff -Nru spip-4.4.21+dfsg/prive/objets/liste/auteurs_associer.html spip-4.4.23+dfsg/prive/objets/liste/auteurs_associer.html --- spip-4.4.21+dfsg/prive/objets/liste/auteurs_associer.html 2026-08-12 09:11:36.000000000 +0000 +++ spip-4.4.23+dfsg/prive/objets/liste/auteurs_associer.html 2026-09-02 11:45:16.000000000 +0000 @@ -71,7 +71,7 @@ [] [(#TRI{statut,#CHEMIN_IMAGE{auteur-0minirezo-16.png}|balise_img{<:lien_trier_statut|attribut_html:>},ajax})] - [(#TRI{multi nom,<:info_nom:>,ajax})] + [(#TRI{multi nom,<:info_nom:>,ajax})] [(#GET{auteurs_voiremails})[(#TRI{email,<:email:>,ajax})]]   @@ -80,7 +80,7 @@ [(#STATUT|puce_statut{auteur})] - [(#RANG). ][(#NOM|sinon{<:texte_vide:>})] + [(#RANG). ][(#NOM|sinon{<:texte_vide:>})] [] [(#GET{auteurs_voiremails})[[(#EMAIL|couper{30})]]] diff -Nru spip-4.4.21+dfsg/prive/themes/spip/lists.css.html spip-4.4.23+dfsg/prive/themes/spip/lists.css.html --- spip-4.4.21+dfsg/prive/themes/spip/lists.css.html 2026-08-12 09:11:36.000000000 +0000 +++ spip-4.4.23+dfsg/prive/themes/spip/lists.css.html 2026-09-02 11:45:16.000000000 +0000 @@ -295,7 +295,7 @@ /* Sur petit écran, n'afficher que les colonnes nécessaires : statut et id */ @media (max-width: 760px) { - .liste-objets tr > *:not(.principale):not(.id):not(.statut), + .liste-objets tr > *:not(:where(.principale,.id, .statut, .action)), .liste-objets .titre .soustitre, .liste-objets .titre .surtitre { display: none; @@ -625,7 +625,7 @@ * N'afficher que les colonnes nécessaires : statut et id * @extend .mini */ -.lat .liste-objets tr > *:not(.principale):not(.id):not(.statut), +.lat .liste-objets tr > *:not(:where(.principale, .id, .statut, .action)), .lat .liste-objets .titre .soustitre, .lat .liste-objets .titre .surtitre { display: none; diff -Nru spip-4.4.21+dfsg/vendor/composer/installed.json spip-4.4.23+dfsg/vendor/composer/installed.json --- spip-4.4.21+dfsg/vendor/composer/installed.json 2026-08-20 11:47:08.000000000 +0000 +++ spip-4.4.23+dfsg/vendor/composer/installed.json 2026-09-02 12:03:00.000000000 +0000 @@ -329,17 +329,17 @@ }, { "name": "spip/ecrire", - "version": "4.4.21", - "version_normalized": "4.4.21.0", + "version": "4.4.23", + "version_normalized": "4.4.23.0", "source": { "type": "git", "url": "https://git.spip.net/spip/ecrire.git", - "reference": "be104d012aceda0049347121ddc2477c91a79487" + "reference": "f315d717675c54ad2c84411bb8c2d3c26297a0b5" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=be104d012aceda0049347121ddc2477c91a79487", - "reference": "be104d012aceda0049347121ddc2477c91a79487", + "url": "https://git.spip.net/api/v4/projects/spip%2Fecrire/repository/archive.zip?sha=f315d717675c54ad2c84411bb8c2d3c26297a0b5", + "reference": "f315d717675c54ad2c84411bb8c2d3c26297a0b5", "shasum": "" }, "require": { @@ -361,7 +361,7 @@ "require-dev": { "symplify/easy-coding-standard": "^12.3" }, - "time": "2026-08-20T13:41:29+02:00", + "time": "2026-09-02T13:56:18+02:00", "type": "spip-ecrire", "installation-source": "dist", "autoload": { @@ -377,30 +377,30 @@ ], "description": "Noyau de SPIP", "support": { - "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.21", + "source": "https://git.spip.net/spip/ecrire/-/tree/4.4.23", "issues": "https://git.spip.net/spip/ecrire/-/issues" }, "install-path": "../../ecrire" }, { "name": "spip/prive", - "version": "1.1.3", - "version_normalized": "1.1.3.0", + "version": "1.1.5", + "version_normalized": "1.1.5.0", "source": { "type": "git", "url": "https://git.spip.net/spip/prive.git", - "reference": "7679959803b8e40ae029a15f757c4ae171802cae" + "reference": "7ed90bbcf72fc33213bc0257bc3e805bd6c5a067" }, "dist": { "type": "zip", - "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=7679959803b8e40ae029a15f757c4ae171802cae", - "reference": "7679959803b8e40ae029a15f757c4ae171802cae", + "url": "https://git.spip.net/api/v4/projects/spip%2Fprive/repository/archive.zip?sha=7ed90bbcf72fc33213bc0257bc3e805bd6c5a067", + "reference": "7ed90bbcf72fc33213bc0257bc3e805bd6c5a067", "shasum": "" }, "require-dev": { "spip-league/kernel": "^1.x-dev" }, - "time": "2026-08-12T11:11:37+02:00", + "time": "2026-09-02T13:45:16+02:00", "type": "spip-prive", "installation-source": "dist", "license": [ @@ -408,7 +408,7 @@ ], "description": "Squelettes de l'espace privé", "support": { - "source": "https://git.spip.net/spip/prive/-/tree/1.1.3", + "source": "https://git.spip.net/spip/prive/-/tree/1.1.5", "issues": "https://git.spip.net/spip/prive/-/issues" }, "install-path": "../../prive" diff -Nru spip-4.4.21+dfsg/vendor/composer/installed.php spip-4.4.23+dfsg/vendor/composer/installed.php --- spip-4.4.21+dfsg/vendor/composer/installed.php 2026-08-20 11:47:08.000000000 +0000 +++ spip-4.4.23+dfsg/vendor/composer/installed.php 2026-09-02 12:03:00.000000000 +0000 @@ -1,9 +1,9 @@ array( 'name' => 'spip/spip', - 'pretty_version' => '4.4.21', - 'version' => '4.4.21.0', - 'reference' => 'cb90dd9f41974d19a1b3c2a0055032d9f286d0d7', + 'pretty_version' => '4.4.23', + 'version' => '4.4.23.0', + 'reference' => 'c7ed36e0495640fa924ea3dfab34b20651af9f75', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -71,18 +71,18 @@ 'dev_requirement' => false, ), 'spip/ecrire' => array( - 'pretty_version' => '4.4.21', - 'version' => '4.4.21.0', - 'reference' => 'be104d012aceda0049347121ddc2477c91a79487', + 'pretty_version' => '4.4.23', + 'version' => '4.4.23.0', + 'reference' => 'f315d717675c54ad2c84411bb8c2d3c26297a0b5', 'type' => 'spip-ecrire', 'install_path' => __DIR__ . '/../../ecrire', 'aliases' => array(), 'dev_requirement' => false, ), 'spip/prive' => array( - 'pretty_version' => '1.1.3', - 'version' => '1.1.3.0', - 'reference' => '7679959803b8e40ae029a15f757c4ae171802cae', + 'pretty_version' => '1.1.5', + 'version' => '1.1.5.0', + 'reference' => '7ed90bbcf72fc33213bc0257bc3e805bd6c5a067', 'type' => 'spip-prive', 'install_path' => __DIR__ . '/../../prive', 'aliases' => array(), @@ -98,9 +98,9 @@ 'dev_requirement' => false, ), 'spip/spip' => array( - 'pretty_version' => '4.4.21', - 'version' => '4.4.21.0', - 'reference' => 'cb90dd9f41974d19a1b3c2a0055032d9f286d0d7', + 'pretty_version' => '4.4.23', + 'version' => '4.4.23.0', + 'reference' => 'c7ed36e0495640fa924ea3dfab34b20651af9f75', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(),