Sécuriser l'edition d'un auteur #5256

Merged
marcimat merged 4 commits from issue_4833_editer_auteur into master 3 months ago
  1. 3
      CHANGELOG.md
  2. 2
      ecrire/public/composer.php
  3. 24
      prive/formulaires/editer_auteur.php
  4. 13
      prive/javascript/ajaxCallback.js
  5. 3
      prive/squelettes/objet.html
  6. 3
      prive/squelettes/page.html
  7. 17
      prive/themes/spip/forms.css.html

3
CHANGELOG.md

@ -4,6 +4,7 @@
### Security
- #5256 Bloquer la modification d'un auteur via une XMLHttpRequest ou une iframe
- spip-team/securite#4832 Envoyer un CSP sandbox sur tous les documents de IMG via une RewriteRule du htaccess.txt modèle
- spip-team/securite#4835 Mise a jour de l'écran de sécurité en version 1.4.2
- spip-team/securite#4835 Sécuriser le paramètre `_oups` dans le formulaire d'édition de liens
@ -24,6 +25,8 @@
### Fixed
- #5256 Correction de `#HTTP_HEADER{}` quand la valeur contenait un simple quote
- #5256 Corriger `refuser_traiter_formulaire_ajax()` qui ne fonctionnait pas quand un form contenait un element avec un name ou id `submit`
- spip-contrib-extensions/formidable#119 Échapper les noms de fichier quand on génère une balise img à l'aide du filtre `|balise_img`
- #4826 Vignettes fallback quand on ne sait par reduire la taille d'une image du fait de son format
- #5232 Correction notice PHP sur `signale_edition()`

2
ecrire/public/composer.php

@ -218,7 +218,7 @@ function analyse_resultat_skel($nom, $cache, $corps, $source = '') {
if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
$headers[$j] .= '|' . $r[3];
} else {
$headers[$j] = $r[3];
$headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'],$r[3]);
}
}
}

24
prive/formulaires/editer_auteur.php

@ -326,10 +326,32 @@ function formulaires_editer_auteur_traiter_dist(
$row = [],
$hidden = ''
) {
$id_objet = null;
if (_request('saisie_webmestre') or _request('webmestre')) {
set_request('webmestre', _request('webmestre') ?: 'non');
}
// si il y a des modifs sensibles (statut, mot de passe), on refuse le traitement en ajax
// le formulaire ne peut être traité depuis une XMLHttpRequest
$prev = formulaires_editer_objet_charger('auteur', $id_auteur, 0, 0, $retour, $config_fonc, $row, $hidden);
if (
_request('new_pass') // nouveau mot de passe
or empty($prev['statut']) // creation auteur
or (_request('email') and $prev['email'] !== _request('email')) // modification email
or (_request('statut') === '0minirezo' and $prev['statut'] !== '0minirezo') // promotion 0minirezo
or (_request('statut') and intval(_request('statut')) < intval($prev['statut'])) // promotion de statut
or (_request('webmestre') and _request('webmestre') !== 'non' and $prev['webmestre'] !== 'oui') // promotion webmestre
) {
refuser_traiter_formulaire_ajax();
// si on arrive là encore en ajax c'est pas OK, on genere une erreur
if (_AJAX or !empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
return [
'message_erreur' => _T('erreur_technique_ajaxform')
];
}
}
$id_objet = null;
$retour = parametre_url($retour, 'email_confirm', '');
if ($restreintes = _request('restreintes')) {

13
prive/javascript/ajaxCallback.js

@ -287,7 +287,7 @@ jQuery.fn.formulaire_dyn_ajax = function(target) {
if (leclk) {
scrollwhensubmit_button = !jQuery(leclk).is('.noscroll');
var n = leclk.name;
if (n && !leclk.disabled && leclk.type == "image") {
if (n && !leclk.disabled && leclk.type === "image") {
leclk_x = leform.clk_x;
leclk_y = leform.clk_y;
}
@ -312,13 +312,20 @@ jQuery.fn.formulaire_dyn_ajax = function(target) {
var n = leclk.name;
if (n && !leclk.disabled) {
jQuery(leform).prepend("<input type='hidden' name='"+n+"' value='"+leclk.value+"' />");
if (leclk.type == "image") {
if (leclk.type === "image") {
jQuery(leform).prepend("<input type='hidden' name='"+n+".x' value='"+leform.clk_x+"' />");
jQuery(leform).prepend("<input type='hidden' name='"+n+".y' value='"+leform.clk_y+"' />");
}
}
}
jQuery(leform).ajaxFormUnbind().submit();
jQuery(leform).ajaxFormUnbind().closest('.formulaire_spip').addClass('resubmit-noajax');
try {
leform.submit();
} catch (err) {
// just in case form has element with name/id of 'submit'
var submitFn = document.createElement('form').submit;
submitFn.apply(leform);
}
}
else {
if (!c.length || c.indexOf("ajax-form-is-ok")==-1)

3
prive/squelettes/objet.html

@ -1 +1,2 @@
<INCLURE{fond=prive/squelettes/structure}{env}{type=#ENV{page,#ENV{type}}}{composition=#ENV{composition,''}}>
#HTTP_HEADER{"Content-Security-Policy: frame-ancestors 'none'"}
<INCLURE{fond=prive/squelettes/structure}{env}{type=#ENV{page,#ENV{type}}}{composition=#ENV{composition,''}}>

3
prive/squelettes/page.html

@ -1 +1,2 @@
<INCLURE{fond=prive/squelettes/structure}{env}{type-page=#ENV{type-page,#ENV{exec}}}{composition=#ENV{composition,''}}>
#HTTP_HEADER{"Content-Security-Policy: frame-ancestors 'none'"}
<INCLURE{fond=prive/squelettes/structure}{env}{type-page=#ENV{type-page,#ENV{exec}}}{composition=#ENV{composition,''}}>

17
prive/themes/spip/forms.css.html

@ -1652,3 +1652,20 @@ img.aide {
top: 50%;
transform: translateY(-50%);
}
@keyframes skew-x-shakeng{
0% { transform: skewX(-4deg); }
5% { transform: skewX(4deg); }
10% { transform: skewX(-4deg); }
15% { transform: skewX(4deg); }
20% { transform: skewX(-4deg); }
25% { transform: skewX(4deg); }
30% { transform: skewX(-4deg); }
35% { transform: skewX(4deg); }
40% { transform: skewX(0deg); }
100% { transform: skewX(0deg); }
}
.formulaire_spip.resubmit-noajax {
animation: skew-x-shakeng 0.5s;
}

Loading…
Cancel
Save