Em quais contextos os plug-ins são responsáveis ​​pela validação / higienização de dados?

17

Quero garantir que todos os dados nos meus plugins / temas sejam tratados com segurança antes de entrar no banco de dados e antes de serem enviados ao navegador. Meu problema é que há situações em que a API lida com a higienização para você - como ao salvar os meta-campos de postagem - e outras onde o autor do plugin / tema é totalmente responsável por fazê-lo - como ao salvar configurações personalizadas.

Para o escopo desta pergunta, não estou preocupado em validar dados no nível do domínio - por exemplo, verificar se um campo Idade em um formulário está entre 0 e 120 ou se um endereço de email é válido. Estou preocupado apenas com segurança - por exemplo, escapar de consultas SQL para evitar a injeção de SQL ao salvar no banco de dados ou desinfetar dados que saem para modelos HTML para evitar XSS.

Para higienização de saída, eu sei que você sempre precisa usar funções como esc_html()e esc_attr()ao ecoar variáveis ​​em modelos HTML. Mas e quando usar tags de modelo ? Todos eles já limpam a saída? Em caso afirmativo, para qual contexto (HTML geral, atributos de tag etc.)? Algumas funções têm variantes para diferentes contextos (como the_title_attribute(), mas a maioria não.

Para higienização de entrada, eu sei que preciso usar $wpdb->prepare()ao fazer consultas manuais, mas e quando usar a API de configurações para criar uma página de configurações de plug-in ou salvar os meta-campos de postagem para um tipo de postagem personalizado?

No momento, acabei de pesquisar no Core e ler os tutoriais toda vez que uso uma função para descobrir se ela higieniza ou não, mas isso é propenso a erros e consome muito tempo. Espero encontrar algum tipo de lista abrangente de todas as situações possíveis e se a API lida com isso ou não. por exemplo,

A API valida / higieniza

  • Salvando meta meta com update_postmeta()
  • Salvando a meta do usuário com update_user_meta()
  • Saída de um título de postagem - use a variante contextualmente apropriada de the_title()
  • etc

Você precisa validar / higienizar manualmente

  • Salvando opções de plug-in com a API de configurações. Passe um retorno de chamada como o terceiro parâmetro de register_setting().
  • Consultas diretas ao banco de dados: envolva a consulta $wpdb->prepare().
  • Saída de variáveis ​​em HTML. Use esc_attr(), esc_html(), etc
  • etc

Também estaria interessado em entender por que a API a fornece em determinadas situações, mas não em outras. Suponho que tenha algo a ver com a natureza desconhecida dos dados, mas gostaria de ouvir uma explicação completa.

Ian Dunn
fonte
Eu gosto dessa pergunta. Eu tenho o mesmo pensamento que você. Eu acho que se houver uma lista de quando devemos validar / higienizar manualmente, isso seria ótimo. +1.
Anh Tran
11
@Rilwis, por favor, veja minha resposta. Você deve sempre validar. A higienização é mais complicada, pois 'seguro' depende do contexto. Geralmente, se você estiver usando a API do WordPress com dados conhecidos do WordPress ( the_title(), the_permalink()etc), você estará bem, mas com dados personalizados, não (por exemplo get_post_meta()). Em caso de dúvida, higienize a si mesmo - não pode machucar.
Stephen Harris
@StephenHarris: Eu li o seu comentário. Eu também sei disso. Mas tenho a mesma opinião que Ian Dunn. Eu acho que a principal razão pela qual ele pergunta é "faça o suficiente, nem mais, nem menos".
Anh Tran
11
Na verdade, eu não me importo de errar por precaução e fazer muita validação / saneamento, mas acho que há casos em que escapar das coisas duas vezes pode ser um problema.
11111 Ian Dunn

Respostas:

15

Existem dois conceitos aqui:

  • validação - certificando-se de que os dados são válidos , ou seja, um número inteiro é um número inteiro, uma data é uma data (no formato correto etc). Isso deve ser feito antes de salvar os dados.
  • sanitização - tornando a data segura para uso no contexto atual (por exemplo, escapando de consultas SQL ou escapando de HTML na saída).

A validação é, quase universalmente, exclusivamente sua . Você sabe quais dados você está solicitando de um usuário e quais dados você espera - o WordPress não. A validação seria realizada, por exemplo, no save_postgancho antes de salvá-lo no banco de dados update_post_meta, ou pode ser feita através da especificação de uma função de retorno de chamada na API de configurações, chamada pouco antes do WordPress salvar os dados.

Sanitização é um pouco mais misto. Ao lidar com dados que o WordPress conhece nativamente (por exemplo, o bloco de uma postagem), você pode ter certeza de que o WordPress já tornou os dados seguros. No entanto, 'seguro' depende do contexto; o que é seguro para uso em uma página, não é necessariamente seguro como um atributo do elemento. Daí WordPress terão funções diferentes para o contexto diferente (por exemplo the_title(), the_title_rss(), the_title_attribute()) - então você precisa usar o caminho certo .

Na maioria das vezes, seu plug-in pode lidar com pós-meta - ou talvez dados de eventos de uma tabela personalizada. O WordPress não sabe para que servem esses dados ou para que servem, portanto, certamente não sabe como torná-los seguros. Isso é com você . Isso é particularmente importante no uso de esc_url(), etc esc_attr(), esc_textarea()para impedir que entradas maliciosas possam incorporar código. Como o WordPress sabe que next_posts()é suposto imprimir um URL para a página, ele se aplica esc_url()- mas com o post meta, por exemplo, ele não sabe que armazena um URL - ou o que você quer fazer com ele (se estiver imprimindo esc_url(), se estiver redirecionando esc_url_raw(). Se estiver dobut - erre no lado da cautela e escape sozinho - e faça isso o mais tarde possível.

Finalmente - e quanto a salvar dados? Você precisa torná-lo seguro, então? Como mencionado você fazer necessidade de garantir que os dados é válido. Mas se estiver usando WordPress API ( wp_insert_post(), update_post_meta()etc), então você não precisa higienizar os dados - porque quando salvar dados a única saneantes que você precisa fazer é escapar instruções SQL - e WordPress faz isso. Se você estiver executando instruções SQL diretas (digamos, para ler / gravar dados de uma tabela personalizada), deverá usar a $wpdbclasse para ajudá-lo a limpar suas consultas.

Eu escrevi este post sobre sanitização e validação de dados que você pode achar útil - falo sobre o que é esperado de você a esse respeito.

Stephen Harris
fonte
Hey Stephan, obrigado pela explicação. Isso me ajudou a entender um pouco melhor, mas o que realmente estou procurando é uma espécie de lista abrangente, como o exemplo que dei. Parece que sua abordagem é adivinhar se o WP lida com isso ou não, ou errar por precaução e sempre higienizar. Eu me sentiria mais confiante com isso se tivesse uma lista abrangente e autorizada, em vez de confiar no meu entendimento. Também estou preocupado que a fuga dupla possa levar a problemas.
Ian Dunn
Também atualizei a questão para esclarecer algumas coisas.
Ian Dunn
0

Não tenho certeza se é tão completo, mas com qualquer plug-in ou tema, a entrada do usuário deve ser higienizada. As operações do banco de dados devem ser feitas usando os métodos $ wpdb->. Todos os dados $ _GET e $ _POST devem ser limpos.

Essa é mais prática recomendada para programação PHP do que o WordPress.

Portanto, em conclusão, se houver uma função do WordPress, use-a, caso contrário, desinfete suas variáveis ​​e insira você mesmo.

Se eu fosse muito vago, faça uma pergunta mais específica.

Ciprian
fonte
3
Entendo que ele sempre precisa ser higienizado, mas a pergunta é sobre quem faz a higienização em cada situação específica. Às vezes, o WordPress faz isso automaticamente, e às vezes você precisa fazer isso manualmente. Atualizei a pergunta para tentar torná-la mais clara.
31512 Ian
Mesmo ao usar update_user_meta (), você ainda precisa validá-lo, pois os valores atualizados podem vir de um formulário exposto ou da entrada de um usuário. Se for um valor proveniente de um script, como uma decisão interna, de um loop if / else, você não deve limpá-lo.
Ciprian
11
O valor que você passa para update_user_meta()é passado através de stripslashes_deep()e sanitize_meta()em update_metadata(), e depois $wpdb->prepare()em $wpdb->update(). Então, acho que você não precisa higienizar. Estou esquecendo de algo?
11114 Ian