O sanitize_text_field ( método WordPress para limpar campos ) para limpar caminho de arquivos? Não faça isso.

O que é o sanitize_text_field?

É um método responsável por limpar ou filtrar strings ineridos no input text pelo usuário ou pelo banco de dados.

A documentação e muitos posts e recomendam o uso para proteção de inputs fields.

Mas não existe bala de prata. Você pode ver melhor na documentação do método no site do WordPress.

Mas o que ele limpa e o que ele protege?

Ele não protege tudo. Na última semana nós mostramos um caso real explorando o método rename() do PHP.

Caso real explorando método rename() do PHP.

Nesse caso o developer tentou proteger o input com sanitize_text_field para limpar o valor.

Se ele tentou proteger de XSS ele estava meio certo. No próximo post eu vou mostrar como explorar um XSS bypass. Mas isso é assunto para outro dia.

O sanitize_text_field promete limpar mas não promete limpar quase tudo mas não promete limpar valores usado para fazer hacking usando path traversal. ( Ataque que explora a navegação em pastas para fazer alguma coisa ), como o usso do ../../ para voltar pastas.

Nós vamos usar um exemplo real para explicar.

rename('' . SP_CDM_UPLOADS_DIR . ''.$r[$i]['uid'].'/'.$r[$i]['file'].'', '' . SP_CDM_UPLOADS_DIR . '' . sanitize_text_field($_POST['uid']) . '/'.$r[$i]['file'].'');

Nosso valor é ‘../../../’.

$_POST['uid'] = '../../../';
sanitize_text_field($_POST['uid'])

Nós vamos olhar para código do core do WordPress agora.

https://core.trac.wordpress.org/browser/tags/5.2/src/wp-includes/formatting.php#L5112

Primeiro ele checa se existe < na minha requisição igual a isso…

if( strpos( $filtered, '<') !== false ) {
...
wp_pre_kses_less_than
...
wp_strip_all_tags
...
}

Como não tenho < eu pulo algumas validações.

Segunda validação, remove quebra de linhas.

if ( !$keep_newlines ) {
$filtered = preg_replace( ‘/[\r\n\t ]+/’, ‘ ‘, $filtered );
}

Nós também não temos quebra de linha em nosso input.

Remove octest strings, usando preg_replace.

while( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match) ) {
$filtered= str_replace( $match[0], '', $filtered);
$found= true;
}

Ok, no input ‘../../../’ não temos octets.

Em resumo, nada no sanitize_text_field para o ataque do path transversal.

http://www.target.com/?foo=../../../wp-config.php

<?php

$file = sanitize_text_field( $_GET['foo'] );

// Result is ../../../wp-config.php

E como podemos resolver esse problema?

Use realpath() of php:

<?php

$file = realpath( $_GET['foo'] );
// Result is wp-config.php

Para cada problema, uma solução. Sempre verifique. Não existe bala de prata.

Na próxima postagem mostraremos como podemos quebrar o sanitize_text_field no campo de texto explorando um XSS.

See you. =)

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *