Por que escapar se o conteúdo não estiver?

8

A função the_contentinterna é 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?

tmdesigned
fonte
Você esqueceuwp_kses_post
Tom J Nowell
É executado através de wp_kses_post na saída? Onde?
tmdesigned

Respostas:

10

Se eu fosse um hacker com acesso ao banco de dados, não adicionaria meu código ao conteúdo de uma postagem?

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.


“Escapar não é apenas proteger dos bandidos. Está apenas tornando nosso software durável. Contra informações aleatórias ruins, informações maliciosas ou contra o mau tempo. ”

Isso é das diretrizes VIP do WordPress sobre como escapar . Tem muito mais a dizer sobre esse assunto, e você deve ler.

Jacob Peattie
fonte
Obrigado, isso é útil. Eu tinha lido um post no VIP sobre como escapar e o autor mencionou especificamente a ideia de alguém ter acesso ao banco de dados, mas não ao servidor. No entanto, acho que seu raciocínio nesse ponto faz mais sentido. E, suponho, às vezes você está escapando do conteúdo vulnerável do banco de dados, mesmo sem alguém ter acesso completo ao banco de dados, ou seja, por meio de um plug-in ou apenas um comentário.
precisa
9

Na verdade, sou um engenheiro da VIP que faz muita revisão de código :) Eu sinalizo muitas falhas de escape.

mas não escapa à saída

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_htmlcapacidade, portanto não pode escapar na saída. Em vez disso, ele é executado wp_kses_postna entrada. Idealmente, você removeria essa capacidade.

Aqui está a implementação no momento atual:

function the_content( $more_link_text = null, $strip_teaser = false ) {
    $content = get_the_content( $more_link_text, $strip_teaser );

    /**
     * Filters the post content.
     *
     * @since 0.71
     *
     * @param string $content Content of the current post.
     */
    $content = apply_filters( 'the_content', $content );
    $content = str_replace( ']]>', ']]>', $content );
    echo $content;
}

O mecanismo ideal para escapar de qualquer coisa que passe pelo the_contentfiltro, por outro lado, é:

echo apply_filters( 'the_content', wp_kses_post( $content ) );

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

O ponto de fuga é gerar HTML válido, a segurança adicional que ele fornece é apenas um bom efeito colateral.

Para impedir que os usuários quebrem acidentalmente a marcação

Há muitas razões para escapar, mas, fundamentalmente, você está reforçando as expectativas. Pegue o seguinte código:

<a href="<?=$url?>">

Esperamos $urlconter um URL adequado para um hrefatributo, mas e se não for? Bem, por que deixá-lo ao acaso, vamos aplicá-lo:

<a href="<?=esc_url( $url )?>">

Agora sempre será um URL. Não importa se um hacker coloca uma imagem $urlou 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:

  • higienizar cedo
  • validar cedo
  • escapar tarde
  • escapar frequentemente

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_contentnã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:

add_filter( 'the_content' function( $content ) {
    return wp_kses_post( $content );
}, PHP_INT_MAX + 1 );

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_contentescaparã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 o unfiltered_htmlrecurso de todas as funções

Tom J Nowell
fonte
1
Obrigado pela perspectiva adicional. Na verdade, eu tinha lido sua postagem sobre esse assunto no seu site e fiquei imaginando se você teria algo a acrescentar.
precisa
4

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 ksesfunçõ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 o the_contentfiltro 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.

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?

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 _ee '__` 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".

Mark Kaplun
fonte
Obrigado, Mark, pela perspectiva adicional.
tmdesigned
2

Se eu fosse um hacker com acesso ao banco de dados, não adicionaria meu código ao conteúdo de uma postagem?

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.

butlerblog
fonte
Obrigado pela sua resposta. Eu acho que fiquei muito focado na idéia de impedir um hacker de sentir falta da floresta por causa das árvores.
tmdesigned