Sanitização de dados: práticas recomendadas com exemplos de código

15

Estou tentando entender a higienização de dados (não a validação de dados) para me ajudar a escrever temas seguros para o WordPress. Pesquisei na Internet tentando encontrar um guia abrangente para desenvolvedores de temas, detalhando as melhores práticas. Me deparei com alguns recursos, incluindo a página do codex intitulada Validação de Dados, embora nenhum fosse útil para mim. A página do codex lista as funções de higienização disponíveis, seu uso e o que elas fazem, mas falha ao explicar por que você usaria uma sobre a outra ou em que situação você usaria uma função de higienização específica. O objetivo desta publicação é solicitar a todos que contribuam com exemplos de código inválido / não autorizado e como ele deve ser reescrito para uma limpeza adequada. Pode ser um código geral para higienizar o título da postagem ou post thumnails src ou códigos mais elaborados que lidam com a higienização de$_POST dados para solicitações do Ajax.

Além disso, eu gostaria de saber se as funções do WordPress para adicionar / atualizar o banco de dados (por exemplo, as mencionadas no bloco de código abaixo) cuidam automaticamente do trabalho de higienização para você? Se sim, existem exceções quando você tomaria medidas adicionais para limpar os dados enviados para essas funções do WordPress?

add_user_meta
update_user_meta
add_post_meta
update_post_meta
//just to name a few

Além disso, a higienização precisa ser feita de maneira diferente ao ecoar HTML no PHP e contra o PHP embutido no HTML? Para ser mais claro sobre o que estou perguntando, aqui está o código:

<?php echo '<div class="some-div ' . $another_class . '" data-id="' . $id . '" >' . $text . '</div>'; ?>

<div class="some-div <?php echo $another_class; ?>" data-id="<?php echo $id; ?>"><?php echo $text; ?></div>

Ambas as afirmações acima alcançam a mesma coisa. Mas eles precisam ser santificados de maneira diferente?

John
fonte
11
Poderia ajudar se soubéssemos o que você estava tentando higienizar. Os temas são para apresentação de dados ... você só precisa limpar os dados que o usuário está enviando para você, e os envios geralmente são tratados por plug-ins.
EAMann
A função @EAMann Escaping, como esc_attr, esc_html etc, é criada para escapar da saída. Corrija-me se eu estiver errada. Apresentar dados significa que você está produzindo dados, portanto é necessário escapar também dentro dos temas. Caso contrário, não haveria necessidade das funções esc. Quero entender a higienização dos temas do WordPress como um todo e não se limitar à higienização de um ou dois fragmentos de código.
John John
"Apresentar dados significa que você está produzindo dados, portanto também é necessário escapar dentro dos temas" - não. Mais uma vez, você só tem que escapar de dados que você não confia
onetrickpony
@OneTrickPony Está ficando mais claro para mim. Apenas para ter certeza absoluta de que estou entendendo isso - eu escaparia do conteúdo do comentário, mas não escaparia do ID do comentário ou do ID da postagem, se fosse para produzi-los em HTML. Desculpe, realmente incomodá-lo com perguntas uma após a outra.
John John
2
"Você só precisa escapar de dados em que não confia" - concordo plenamente. A única coisa que eu gostaria de acrescentar é que você nunca deve dados de confiança;)
Ian Dunn

Respostas:

12

Esta página do codex explica muito bem, eu acho.

A função mais importante e mais usada é provavelmente esc_attr. Veja este exemplo:

<a href="<?php print $author_url; ?>" title="<?php print $author_name; ?>"> 
  <?php print $author_name; ?>
</a>

Se $author_namecontém um "personagem, você fecha seu atributo e, se ele for seguido onclick="do_something();", pode piorar :)

Doing print esc_attr($author_name)garante que esses caracteres sejam codificados e o navegador não faz o que não deveria.

Há um caso em que você não precisa: quando você está esperando um número, nesse caso, você pode simplesmente converter os dados de entrada em números inteiros, por exemplo:

print (int)$_POST['some_number'];


As funções meta * listadas lá já cuidam da limpeza da entrada para armazenamento de banco de dados, para que você não precise se preocupar com isso.

O wpdb->prepare()método precisa ser usado quando você mesmo faz as consultas ao banco de dados. Aqui está um exemplo:

$sql = $wpdb->prepare('
    UPDATE wp_posts SET post_title = %s WHERE ID = %d', 
      $_POST['title'], $_POST['id']);

$wpdb->query($sql);

As palavras %s- %dchave e serão substituídas pelos seus valores higienizados de $ _POST.

Um erro muito comum que vejo em muitos plugins no repositório do WP.org é passar uma consulta já preparada para ele (e mal preparada), como:

$wpdb->prepare('UPDATE wp_posts SET post_title = \''.$_POST['title'].' WHERE ...

Não faça isso :)

Além disso, a higienização precisa ser feita de maneira diferente ao ecoar HTML no PHP e contra o PHP embutido no HTML?

Ambas as afirmações acima alcançam a mesma coisa. Mas eles precisam ser santificados de maneira diferente?

Não.

onetrickpony
fonte
Thx por suas entradas. Sua explicação torna as coisas mais claras para mim.
John
É necessário um pequeno esclarecimento. Se eu passar uma string para uma var (por exemplo, $ var = 'string';) dentro do PHP e repeti-la como um atributo HTML, eu desinfecto a $ var quando estiver ecoando. Ou a higienização só é necessária se eu tiver extraído o valor de $ var do banco de dados.
John
Quando ecoando-lo na tela, de alguma forma ou de outra
onetrickpony
Portanto, se eu entendi corretamente, se eu passei a string para $ var dentro do código PHP ou extraí dados do banco de dados e passei para $ var, ambos exigem que eu escute a saída. Corrigir?
John
Sim, se esses dados vierem como entrada do usuário, como, por exemplo, o nome do autor de um comentário. Se por "passou a string para $ var dentro do código PHP" você quer dizer que atribuiu um valor que conhece a uma variável, obviamente - não, você não precisa higienizar essa variável
onetrickpony