Browse Source

fix: securisation du formulaire d'upload d'un plugin depuis un zip arbitraire ainsi que du formulaire d'ajout de nouveaux dépots ;

dans les 2 cas on demande au webmestre de saisir son mot de passe pour securiser l'action

Refs: spip-team/securite#4832 et spip-team/securite#4833
pull/4856/head
Cerdic 3 months ago
parent
commit
bf5756eb1f
  1. 3
      action/teleporter.php
  2. 12
      formulaires/ajouter_depot.html
  3. 49
      formulaires/ajouter_depot.php
  4. 14
      formulaires/charger_plugin_archive.html
  5. 67
      formulaires/charger_plugin_archive.php
  6. 1
      lang/svp_fr.php

3
action/teleporter.php

@ -33,6 +33,9 @@ function action_teleporter_composant_dist($methode, $source, $dest, $options = [
if (!preg_match(',' . substr(_DIR_LIB, 0, -1) . ',', $dest) && !_DIR_PLUGINS_AUTO) {
die('Vous ne pouvez pas télécharger, absence de _DIR_PLUGINS_AUTO');
}
if (!autoriser('ajouter', '_plugins')){
return _T('svp:erreur_teleporter_chargement_source_impossible', ['source' => $source]);
}
// verifier que la methode est connue
if (!$teleporter = charger_fonction($methode, 'teleporter', true)) {

12
formulaires/ajouter_depot.html

@ -19,14 +19,20 @@
<a class="spip_out" title="<:svp:bulle_ajouter_spipzone:>" href="https://plugins.spip.net/depots/principal.xml" onclick="$('#xml_paquets').attr('value',$(this).attr('href')).focus();return false;"><:svp:info_adresse_spipzone:></a> <i>(<a class="spip_out" href="https://plugins.spip.net/spip.php?page=depots" onclick="window.open(this.href); return false;"><:svp:titre_liste_depots:></a>)</i>
</p>
[<span class="erreur_message">(#ENV{erreurs}|table_valeur{xml_paquets})</span>]
<input type="text" name="xml_paquets" id="xml_paquets" value="[https://plugins.spip.net/depots/principal.xml(#ENV{nb_depots}|non)]" class="text" />
<input type="text" name="xml_paquets" id="xml_paquets" value="#ENV{xml_paquets}" class="text" />
</div>
<div class="editer editer_password[(#ENV{erreurs/password}|oui) erreur]">
<label for="password"><:entree_mot_passe:></label>
[<span class="erreur_message">(#ENV**{erreurs/password})</span>]
<input type="password" name="password" id="password" value="#ENV{password}" class="text" />
<p class='explication'><:svp:explication_mot_passe:></p>
</div>
</div>
<p class="boutons">
<input type="submit" class="btn submit" value="<:bouton_ajouter:>" />
</p>
</div>
</form>
]
</div>
</div>

49
formulaires/ajouter_depot.php

@ -25,8 +25,10 @@ function formulaires_ajouter_depot_charger_dist() {
}
// On ne renvoie pas les valeurs saisies mais on fait un raz systematique
$nb = (int)sql_countsel('spip_depots');
return [
'nb_depots' => (int)sql_countsel('spip_depots'),
'xml_paquets' => $nb ? '' : "https://plugins.spip.net/depots/principal.xml",
'password' => '',
];
}
@ -43,17 +45,40 @@ function formulaires_ajouter_depot_charger_dist() {
function formulaires_ajouter_depot_verifier_dist() {
$erreurs = [];
$xml = trim(_request('xml_paquets'));
if (!$xml) {
// L'url est obligatoire
$erreurs['xml_paquets'] = _T('svp:message_nok_champ_obligatoire');
} elseif (!svp_verifier_adresse_depot($xml)) {
// L'url n'est pas correcte, le fichier xml n'a pas ete trouve
$erreurs['xml_paquets'] = _T('svp:message_nok_url_depot_incorrecte', ['url' => $xml]);
} elseif (sql_countsel('spip_depots', 'xml_paquets=' . sql_quote($xml))) {
// L'url est deja ajoutee
$erreurs['xml_paquets'] = _T('svp:message_nok_depot_deja_ajoute', ['url' => $xml]);
if (!autoriser('ajouter', '_depots')) {
$erreurs['message_erreur'] = _T('svp:erreur_teleporter_chargement_source_impossible', ['source' => '']);
}
else {
if (empty($password = _request('password'))) {
$erreurs['password'] = _T('info_obligatoire');
}
else {
include_spip('inc/auth');
if (!auth_controler_password_auteur_connecte($password)) {
$erreurs['message_erreur'] = _T('svp:erreur_teleporter_chargement_source_impossible', ['source' => '']);
}
}
$xml = trim(_request('xml_paquets'));
if (!$xml){
// L'url est obligatoire
$erreurs['xml_paquets'] = _T('svp:message_nok_champ_obligatoire');
}
if (empty($erreurs)) {
if (!svp_verifier_adresse_depot($xml)) {
// L'url n'est pas correcte, le fichier xml n'a pas ete trouve
$erreurs['xml_paquets'] = _T('svp:message_nok_url_depot_incorrecte', ['url' => $xml]);
} elseif (sql_countsel('spip_depots', 'xml_paquets=' . sql_quote($xml))) {
// L'url est deja ajoutee
$erreurs['xml_paquets'] = _T('svp:message_nok_depot_deja_ajoute', ['url' => $xml]);
}
}
}
if (count($erreurs)) {
set_request('password');
}
return $erreurs;
@ -88,7 +113,9 @@ function formulaires_ajouter_depot_traiter_dist() {
} else {
$retour['message_ok'] = _T('svp:message_ok_depot_ajoute', ['url' => $xml]);
spip_log('ACTION AJOUTER DEPOT (manuel) : url = ' . $xml, 'svp_actions.' . _LOG_INFO);
set_request('xml_paquets');
}
set_request('password');
$retour['editable'] = true;
return $retour;

14
formulaires/charger_plugin_archive.html

@ -1,4 +1,4 @@
<div class='formulaire_spip formulaire_configurer'>
<div class='formulaire_spip formulaire_#FORM'>
<h3 class='titrem'><:svp:titre_form_charger_plugin_archive:></h3>
[<p class="reponse_formulaire reponse_formulaire_ok" role="status">(#ENV*{message_ok})</p>]
@ -12,16 +12,22 @@
<p class='explication'><:svp:telecharger_archive_plugin_explication:></p>
<div class="editer-groupe">
<div class="editer editer_archive haut obligatoire[(#ENV{erreurs/archive}|oui) erreur]">
<div class="editer editer_archive pleine_largeur obligatoire[(#ENV{erreurs/archive}|oui) erreur]">
<label for="archive"><:svp:label_archive:></label>
[<span class="erreur_message">(#ENV**{erreurs/archive})</span>]
<input type="text" name="archive" value="#ENV{archive}" class="text" />
<input type="text" name="archive" id="archive" value="#ENV{archive}" class="text" />
</div>
<div class="editer editer_destination[(#ENV{erreurs/destination}|oui) erreur]">
<label for="destination"><:svp:label_destination:></label>
[<span class="erreur_message">(#ENV**{erreurs/destination})</span>]
<input type="text" name="destination" id="destination" value="#ENV{destination}" class="text" />
<p class='explication'><:svp:explication_destination:></p>
<input type="text" name="destination" value="#ENV{destination}" class="text" />
</div>
<div class="editer editer_password[(#ENV{erreurs/password}|oui) erreur]">
<label for="password"><:entree_mot_passe:></label>
[<span class="erreur_message">(#ENV**{erreurs/password})</span>]
<input type="password" name="password" id="password" value="#ENV{password}" class="text" />
<p class='explication'><:svp:explication_mot_passe:></p>
</div>
</div>
<p class='boutons'><input class='btn submit' type="submit" value="<:bouton_telecharger:>" /></p>

67
formulaires/charger_plugin_archive.php

@ -26,7 +26,8 @@ function formulaires_charger_plugin_archive_charger_dist() {
return [
'archive' => '',
'destination' => ''
'destination' => '',
'password' => ''
];
}
@ -42,33 +43,51 @@ function formulaires_charger_plugin_archive_charger_dist() {
function formulaires_charger_plugin_archive_verifier_dist() {
include_spip('inc/plugin'); // _DIR_PLUGINS_AUTO
$erreurs = [];
if (!$archive = _request('archive')) {
$erreurs['archive'] = _T('info_obligatoire');
} else {
// Validité de l'url de l'archive
$infos_archive = pathinfo($archive);
if (!isset($infos_archive['extension'])) {
$erreurs['archive'] = _T('svp:message_nok_url_archive');
if (!autoriser('ajouter', '_plugins')) {
$erreurs['message_erreur'] = _T('svp:erreur_teleporter_chargement_source_impossible', ['source' => '']);
}
else {
if (!$archive = _request('archive')) {
$erreurs['archive'] = _T('info_obligatoire');
} else {
// calcul du répertoire de destination
if (!$destination = _request('destination')) {
$destination = $infos_archive['filename'];
// Validité de l'url de l'archive
$infos_archive = pathinfo($archive);
if (!isset($infos_archive['extension'])) {
$erreurs['archive'] = _T('svp:message_nok_url_archive');
} else {
// calcul du répertoire de destination
if (!$destination = _request('destination')) {
$destination = $infos_archive['filename'];
}
$destination = str_replace('../', '', $destination);
set_request('destination', $destination);
// si la destination existe, on demande confirmation de l'ecrasement.
$dir = _DIR_PLUGINS_AUTO . $destination;
if (is_dir($dir) and !_request('confirmer')) {
$base = dirname($dir);
$nom = basename($dir);
$backup = "$base/.$nom.bck";
$erreurs['confirmer'] = _T('svp:confirmer_telecharger_dans', [
'dir' => joli_repertoire($dir),
'dir_backup' => joli_repertoire($backup)
]);
}
}
$destination = str_replace('../', '', $destination);
set_request('destination', $destination);
// si la destination existe, on demande confirmation de l'ecrasement.
$dir = _DIR_PLUGINS_AUTO . $destination;
if (is_dir($dir) and !_request('confirmer')) {
$base = dirname($dir);
$nom = basename($dir);
$backup = "$base/.$nom.bck";
$erreurs['confirmer'] = _T('svp:confirmer_telecharger_dans', [
'dir' => joli_repertoire($dir),
'dir_backup' => joli_repertoire($backup)
]);
}
if (empty($password = _request('password'))) {
$erreurs['password'] = _T('info_obligatoire');
}
else {
include_spip('inc/auth');
if (!auth_controler_password_auteur_connecte($password)) {
$erreurs['message_erreur'] = _T('svp:erreur_teleporter_chargement_source_impossible', ['source' => '']);
}
}
}
return $erreurs;

1
lang/svp_fr.php

@ -87,6 +87,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'etat_obsolete' => 'Obsolète',
'etat_verrouille' => 'Verrouillé',
'explication_destination' => 'Le chemin sera calculé depuis le nom de l’archive si vous ne le remplissez pas.',
'explication_mot_passe' => 'Saisissez votre mot de passe pour sécuriser l\'installation',
// F
'fieldset_debug' => 'Débug',

Loading…
Cancel
Save