Blog Ce que révèle l'audit gratuit Partie 1 sur 9

Votre médiathèque est publique

La médiathèque n'est pas un dossier privé, ni sous WordPress ni ailleurs. Comment garder privés les brouillons téléversés sans couper l'API ni casser de liens.

Public par défaut, dans tous les systèmes

Une médiathèque est un dossier sur un serveur web. Téléverser un fichier, c'est le publier. C'est vrai pour WordPress, pour Drupal et pour un site statique ; la seule différence est la facilité avec laquelle on trouve la liste.

Sous WordPress, la liste est à une adresse de distance. L'API REST à /wp-json/wp/v2/media renvoie chaque fichier de la médiathèque à quiconque le demande, sans connexion. La JSON:API de Drupal fait l'équivalent. C'est voulu : la même API alimente l'éditeur de blocs, les galeries, les applications mobiles et les intégrations que votre équipe utilise déjà.

D'où vient la surprise

Les gens traitent la médiathèque comme un Dropbox : un dossier privé où l'on dépose un fichier pour en obtenir un lien. Elle se remplit donc de fichiers que personne ne voulait publier. Le brouillon trois d'un rapport dont le brouillon quatre est celui de la page. Un dossier du conseil téléversé pour qu'une personne puisse le télécharger. Un rapport prévu pour la semaine prochaine, téléversé aujourd'hui.

Deux faits sont confondus. Un fichier vers lequel aucune page ne fait de lien est non lié, pas privé. Un fichier difficile à trouver est caché, pas privé. L'API liste les deux, et un moteur qui trouve l'adresse indexera les deux.

Pourquoi couper l'API est le mauvais correctif

La réponse tentante est de désactiver l'API REST, ou de masquer le point d'accès des médias. C'est de la sécurité par l'obscurité : on bloque une façon de lister les fichiers pendant que chaque adresse directe continue de fonctionner, et on casse les fonctions de l'éditeur et les intégrations qui dépendent de l'API.

La question à trancher est de savoir quels fichiers de la médiathèque doivent être publics. Une fois ce choix fait fichier par fichier, la liste de l'API cesse d'être un problème.

Comment s'y prendre sous WordPress

D'abord, regardez. Ouvrez /wp-json/wp/v2/media?media_type=application sur votre propre site et lisez ce qui revient. N'importe qui sur internet peut voir cette même liste.

Ensuite, décidez fichier par fichier. Les fichiers publics restent. Les brouillons dépassés et tout ce qui n'était jamais destiné à être publié sont supprimés ; une version publiée par rapport. Les fichiers qui doivent exister sans être découvrables sont marqués privés.

Enfin, marquez-les. Nous avons écrit une petite extension exactement pour cela, LFW Private Media : une case Privé sur chaque fichier joint, plus des actions groupées dans la liste des Médias. Un fichier privé disparaît de l'API publique, de la recherche du site, des pages de fichiers joints et des sitemaps, tandis que vos éditeurs continuent de tout voir. Téléchargez-la à LFW.com/dl/lfw-private-media.zip. Si vous préférez voir le mécanisme plutôt que d'installer quoi que ce soit, l'idée entière tient dans un petit fichier :

Afficher le code Masquer le code PHP, 27 lignes
<?php
/**
 * Plugin Name: Private media (minimal)
 * Keeps attachments carrying the meta key _lfw_private out of the public REST API.
 * Editors (anyone who can upload files) still see them.
 */

// The collection: /wp-json/wp/v2/media
add_filter( 'rest_attachment_query', function ( $args ) {
  if ( current_user_can( 'upload_files' ) ) { return $args; }
  $args['meta_query']   = isset( $args['meta_query'] ) ? $args['meta_query'] : array();
  $args['meta_query'][] = array( 'key' => '_lfw_private', 'compare' => 'NOT EXISTS' );
  return $args;
} );

// A single item: /wp-json/wp/v2/media/123
add_filter( 'rest_request_before_callbacks', function ( $response, $handler, $request ) {
  if ( current_user_can( 'upload_files' ) ) { return $response; }
  if ( preg_match( '#^/wp/v2/media/(\d+)$#', $request->get_route(), $m )
       && '1' === get_post_meta( (int) $m[1], '_lfw_private', true ) ) {
    return new WP_Error( 'rest_post_invalid_id', 'Invalid post ID.', array( 'status' => 404 ) );
  }
  return $response;
}, 10, 3 );

// Mark a file private: add the meta key _lfw_private with the value 1.
// With WP-CLI: wp post meta update <attachment-id> _lfw_private 1

Une limite vaut pour l'extension comme pour l'extrait de code. Un fichier déjà public à une adresse directe reste accessible à quiconque a cette adresse. Le marquer privé empêche les inconnus de le découvrir. Cela ne met pas le fichier derrière une authentification. Ce qui est vraiment confidentiel n'a rien à faire dans le dossier des téléversements. Placez-le derrière un téléchargement à accès contrôlé.

Si vous êtes client

Vous n'avez rien à installer. Ouvrez une demande dans votre portail et nous auditerons la médiathèque avec vous, supprimerons ce qui doit partir, marquerons privé ce qui doit rester et installerons l'extension. C'est une petite tâche dans le cadre du forfait, pas un projet à part.

Si vous n'êtes pas encore client, l'audit gratuit vous dira combien de fichiers votre site liste aujourd'hui à quiconque le demande. En voyant ce chiffre, la plupart des gens cessent de traiter la médiathèque comme un Dropbox.

Recevez le LFW Weekly Recap

Une lettre d’information envoyée chaque vendredi avec la semaine chez LFW. Un e-mail par semaine, et aucun autre article du blog.

Nous envoyons d'abord un e-mail de confirmation. Rien d'autre n'arrive avant votre clic.

Lancez l'audit gratuit sur votre site

Ce contrôle fait partie de l'audit gratuit. Saisissez votre domaine pour voir ce qu'il trouve sur votre site.

Informations publiques uniquement. Résultats en une minute environ, en anglais.