Blog O que a auditoria gratuita encontra Parte 1 de 9

A sua biblioteca de mídia é pública

A biblioteca de mídia não é uma pasta privada, nem no WordPress nem em lugar nenhum. Veja como manter privados os rascunhos enviados sem desligar a API nem quebrar links.

Público por padrão, em qualquer sistema

Uma biblioteca de mídia é uma pasta num servidor web. Enviar um arquivo é publicá-lo. Isso vale para o WordPress, para o Drupal e para um site estático; a diferença é só a facilidade de encontrar a lista.

No WordPress, a lista está a um endereço de distância. A API REST em /wp-json/wp/v2/media devolve todos os arquivos da biblioteca para qualquer pessoa que pedir, sem login. A JSON:API do Drupal faz o equivalente. É assim de propósito: a mesma API move o editor de blocos, as galerias, os aplicativos para celular e as integrações que a sua equipe já usa.

De onde vem a surpresa

As pessoas tratam a biblioteca como um Dropbox: uma pasta privada onde se deixa um arquivo para conseguir um link. Então ela se enche de arquivos que ninguém pretendia publicar. O terceiro rascunho de um documento cujo quarto rascunho é o que está na página. A pauta de uma reunião do conselho enviada para que uma única pessoa pudesse baixá-la. Um relatório previsto para a semana que vem, enviado hoje.

Duas coisas se confundem. Um arquivo para o qual nenhuma página faz link está sem link, não privado. Um arquivo difícil de encontrar está escondido, não privado. A API lista os dois, e um buscador que encontrar o endereço vai indexar os dois.

Por que desligar a API é a correção errada

A reação tentadora é desativar a API REST, ou esconder o endpoint de mídia. Isso é segurança por obscuridade: impede uma forma de listar os arquivos enquanto todos os endereços diretos continuam funcionando, e quebra os recursos do editor e as integrações que dependem da API.

A pergunta a responder é quais arquivos da biblioteca devem ser públicos. Depois que você decide isso arquivo por arquivo, a lista da API deixa de ser um problema.

Como tratar isso no WordPress

Primeiro, olhe. Abra /wp-json/wp/v2/media?media_type=application no seu próprio site e leia o que volta. Qualquer pessoa na internet pode ver essa mesma lista.

Segundo, decida arquivo por arquivo. Os arquivos públicos ficam. Os rascunhos superados e tudo o que nunca deveria ser publicado são excluídos; uma versão divulgada por documento. Os arquivos que precisam existir, mas não devem ser encontrados, são marcados como privados.

Terceiro, marque-os. Escrevemos um pequeno plugin exatamente para isso, o LFW Private Media: uma caixa de seleção Privado em cada anexo, mais ações em massa na lista de Mídia. Um arquivo privado desaparece da API pública, da busca do site, das páginas de anexo e dos sitemaps, enquanto os seus editores continuam vendo tudo. Baixe em LFW.com/dl/lfw-private-media.zip. Se preferir ver o mecanismo antes de instalar qualquer coisa, a ideia inteira cabe num arquivo pequeno:

Mostrar o código Ocultar o código PHP, 27 linhas
<?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

Um limite vale tanto para o plugin quanto para o trecho de código. Um arquivo que já é público num endereço direto continua acessível para quem tem esse endereço. Marcá-lo como privado impede que estranhos o descubram. Isso não coloca o arquivo atrás de um login. O que for realmente confidencial nem deve ir para a pasta de uploads. Coloque-o atrás de um download com controle de acesso.

Se você é cliente

Você não precisa instalar nada. Abra um pedido no seu portal e faremos a auditoria da biblioteca com você, excluiremos o que deve sair, marcaremos como privado o que deve ficar e instalaremos o plugin. É uma pequena tarefa dentro da gestão mensal, não um projeto à parte.

Se você ainda não é cliente, a auditoria gratuita vai dizer quantos arquivos o seu site lista hoje para qualquer pessoa que pedir. Ver esse número costuma ser o momento em que as pessoas param de tratar a biblioteca como um Dropbox.

Receba o LFW Weekly Recap

Uma newsletter enviada toda sexta-feira com a semana na LFW. Um e-mail por semana e nenhum outro artigo do blog.

Primeiro enviamos um e-mail de confirmação. Nada mais chega até você clicar.

Faça a auditoria gratuita no seu site

Esta verificação faz parte da auditoria gratuita. Informe o seu domínio para ver o que ela encontra no seu site.

Só informações públicas. Resultados em cerca de um minuto, em inglês.