A função the_content
interna é executada através de vários filtros, mas não escapa à saída. Seria difícil fazer isso, pois é necessário permitir o HTML e até alguns scripts.
Ao gerar, o the_content parece ser executado através desses filtros (a partir do 5.0):
add_filter( 'the_content', 'do_blocks', 9 );
add_filter( 'the_content', 'wptexturize' );
add_filter( 'the_content', 'convert_smilies', 20 );
add_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'shortcode_unautop' );
add_filter( 'the_content', 'prepend_attachment' );
add_filter( 'the_content', 'wp_make_content_images_responsive' );
(and)
add_filter( 'the_content', 'capital_P_dangit' );
add_filter( 'the_content', 'do_shortcode' );
Ele também substitui uma string simples:
$content = str_replace( ']]>', ']]>', $content );
E então get_the_content faz um pouquinho de processamento relacionado ao link "more" e um bug em idiomas estrangeiros.
Nenhum deles impede a injeção de scripts XSS, certo?
Ao salvar, os dados são limpos por meio de wp_kses_post. Mas, como esse é um processo caro, entendo por que não é usado na saída.
A regra básica para escapar do WordPress é que tudo precisa ser escapado, independentemente do saneamento básico e o mais tardar possível. Eu li vários artigos dizendo isso, porque o banco de dados não deve ser considerado uma fonte confiável.
Mas pelas razões acima, the_content não segue isso. Os temas centrais (por exemplo, TwentyNineteen) também não incluem escape adicional na saída.
Então ... por que está ajudando alguma coisa a escapar em outro lugar? Se eu fosse um hacker com acesso ao banco de dados, não adicionaria meu código ao conteúdo de uma postagem?
wp_kses_post
Respostas:
Se você tiver acesso ao banco de dados, é provável que tenha acesso suficiente para que a fuga não o pare. Escapar não ajudará se você tiver sido invadido. Não deveria. Há outras razões para escapar. Os dois principais que eu consigo pensar são:
Para lidar com entradas não autorizadas
O conteúdo da postagem do WordPress é higienizado quando é salvo, mas nem todo o resto é. O conteúdo transmitido por uma string de consulta no URL não é higienizado, por exemplo. O conteúdo dos arquivos de tradução também não é necessariamente. Ambas são fontes de conteúdo que nada têm a ver com o comprometimento do site. Portanto, o texto e o conteúdo traduzíveis extraídos do URL precisam ser escapados.
Para impedir que os usuários quebrem acidentalmente a marcação
Escapar não é apenas por segurança. Você também precisa dele para impedir que os usuários quebrem acidentalmente a marcação do site. Por exemplo, se o usuário que coloca aspas ou
>
símbolos em algum conteúdo do seu plug-in interromper a marcação, você deverá escapar dessa saída. Você não quer ser agressivo demais ao higienizar as entradas, porque há razões perfeitamente válidas para um usuário usar esses caracteres.Isso é das diretrizes VIP do WordPress sobre como escapar . Tem muito mais a dizer sobre esse assunto, e você deve ler.
fonte
Na verdade, sou um engenheiro da VIP que faz muita revisão de código :) Eu sinalizo muitas falhas de escape.
Não é bem assim, não escapa à saída, o que é surpreendente para a maioria das pessoas. Isso ocorre porque, se você é um superadministrador, tem a
unfiltered_html
capacidade, portanto não pode escapar na saída. Em vez disso, ele é executadowp_kses_post
na entrada. Idealmente, você removeria essa capacidade.Aqui está a implementação no momento atual:
O mecanismo ideal para escapar de qualquer coisa que passe pelo
the_content
filtro, por outro lado, é:Dessa forma, tornamos o conteúdo seguro e, em seguida, o executamos pelo filtro, evitando que as incorporações etc. sejam removidas.
So Why Escape
Há muitas razões para escapar, mas, fundamentalmente, você está reforçando as expectativas. Pegue o seguinte código:
Esperamos
$url
conter um URL adequado para umhref
atributo, mas e se não for? Bem, por que deixá-lo ao acaso, vamos aplicá-lo:Agora sempre será um URL. Não importa se um hacker coloca uma imagem
$url
ou se um usuário digita no campo errado ou se há um script malicioso. Sempre será um URL válido, porque dissemos que será um URL. Claro que pode ser um URL muito estranho, mas sempre atenderá às expectativas de que um URL esteja lá. Isso é muito útil, seja para validação de marcação, segurança, etc.Dito isto, escapar não é validação, escapar não é sanitização. Essas são etapas separadas que acontecem em diferentes pontos do ciclo de vida. Escapar obriga as coisas a atender às expectativas, mesmo que isso as consiga.
Às vezes eu gosto de pensar em fugir como uma daquelas mostras de jogos japonesas com a parede gigante de espuma com o recorte. Os participantes precisam se encaixar na forma do cão ou são descartados, apenas para nossos propósitos existem lasers e facas ao redor do buraco. O que sobrar no final terá a forma de um cachorro, e será implacável e rigoroso se você ainda não tiver a forma de um cachorro.
Lembrar:
A segurança é uma etapa múltipla, cebola de múltiplas camadas de defesas, escapar é uma das camadas externas de defesa na saída. Ele pode alterar o código de ataque em um site comprometido, tornando-o inútil, impedir explorações abertas e garantir que seu cliente não interrompa um site colocando tags em um campo que não deveria. Não é um substituto para as outras coisas, e é de longe a ferramenta de segurança mais subutilizada em um manual para desenvolvedores.
Quanto ao porquê de escapar se
the_content
não? Se você tem uma inundação e 5 buracos na parede, mas apenas tempo para consertar 3, você encolhe os ombros e não conserta nenhum? Ou você reduz o risco e reduz a área de ataque?Talvez eu possa ajudar a consertar os dois furos finais com este trecho:
Aqui, definimos a prioridade para o número mais alto possível no PHP e adicionamos 1 para que ele transborde para o número mais baixo possível que pode ser representado. Dessa forma, todas as chamadas para
the_content
escaparão do valor antes de qualquer outro filtro. Dessa forma, as incorporações etc ainda funcionam, mas os usuários não podem se infiltrar em HTML perigoso através do banco de dados. Além disso, procure remover ounfiltered_html
recurso de todas as funçõesfonte
O ponto de fuga é gerar HTML válido, a segurança adicional que ele fornece é apenas um bom efeito colateral.
Os filtros aplicados ao conteúdo geram um HTML válido a partir de algo que é uma mistura de HTML e algum outro texto que possui outra sintaxe, como códigos de acesso. O fato de parte do conteúdo já ser HTML válido impede a aplicação de escape em todo o conteúdo.
Quanto às
kses
funções relacionadas, você não pode aplicá-las principalmente porque não possui contexto suficiente para saber qual delas usar. Por exemplo, pode haver algum processo que use othe_content
filtro para adicionar JS ao conteúdo da postagem, portanto o núcleo não pode adivinhar com base em coisas como o autor da postagem, se a JS for legítima ou não.Novamente, escapar é para gerar HTML válido. De um ponto de vista de segurança, não é que o escape forneça segurança, mas que um código que exija escape deve ser suspeito, pois pode ser mais fácil de explorar. Por exemplo, a maneira como o núcleo usa
_e
e '__` para traduções significa que qualquer pessoa que possa convencê-lo a instalar uma tradução não oficial pode ser capaz de adicionar muito difícil detectar JS no arquivo de tradução e invadir seu site. Este é um bom exemplo de "faça o que eu digo e não o que eu faço".fonte
Eu acho que sua pergunta responde a si mesma. Se você era um hacker com acesso ao banco de dados, já obteve o acesso necessário. A saída de escape não muda nada disso.
O motivo para escapar da saída é avaliar dados não confiáveis para evitar que o hacker obtenha esse acesso em primeiro lugar.
fonte