Melhor maneira de higienizar / filtrar comentários dos usuários?
Pergunta
Atualmente, estou usando esse processo para higienizar/filtrar o comentário inserido pelos usuários ->
Este é usado para tirar barras ... e
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
Então o comentário passa por essa função para higienizar os dados ...
function my_strip_tags($str) {
$strs=explode('<',$str);
$res=$strs[0];
for($i=1;$i<count($strs);$i++)
{
if(!strpos($strs[$i],'>'))
$res = $res.'<'.$strs[$i];
else
$res = $res.'<'.$strs[$i];
}
return strip_tags($res);
}
Depois disso, ele vai direto para o banco de dados usando a declaração preparada.
function add_comment($comment,$type,$update_id,$user_id){
$query="INSERT INTO comment_updates (updateid,userid,comment) VALUES(?,?,?)";
if($stmt=$this->conn->prepare($query)) {
$stmt->bind_param('sss',$update_id,$user_id,$comment);
$stmt->execute();
if($this->conn->affected_rows==1){
$stmt->close();
return true;
}
}
}
Eu só queria saber se isso é seguro o suficiente ou se são outras alternativas melhores ... obrigado
Solução
Não escreva seu próprio desinfetante em HTML. Você criará buracos XSS.
Se você vai escrever o seu próprio, pelo menos execute o Ha.ckers.org XSS SmokeTests contra isso
Entre esses testes e o Comparação de Htmlpurifier, você deve ter uma boa idéia de quão complicada é a higienização de HTML - e por que você deve deixá -lo para os profissionais.
Outras dicas
O mais importante ao pensar em armazenar dados em um banco de dados é escapar dele; usando mysql_real_escape_string
, ou mysqli_real_escape_string
, ou PDO::quote
, dependendo do banco de dados que você está usando (ou outras funções para Oracle/PG/...)
Outra solução seria usar declarações preparadas (ver mysqli::prepare
e/ou PDO::prepare
- aqueles não são suportados pelo antigo mysql_*
extensão), que lidará com os dados escapar em seu lugar ;-)
Ao pensar na saída HTML, você tem duas soluções:
- Aceite HTML e use alguma biblioteca como Htmlpurifier para filtrar/limpar; Ele permitirá especificar exatamente quais tags e atributos são permitidos e fornecerá HTML limpo e válido como saída.
- Tente remover o HTML, como você está fazendo - nem sempre funcionando bem (e se você esquecer algum caso especial?)
- escapar de html, com
htmlentities
ouhtmlspecialchars
: não necessariamente parece bom, mas a saída será com a entrada do usuário.
Eu iria com a primeira ou a última solução; o seu parece mais "perigoso" - mas isso é apenas um sentimento ^^ (a ideia geral é "não reinvente a roda")
Seu manuseio de citações mágicas é bom, embora se você criar parâmetros obtidos com citações, você também precisa para retirar as teclas. :)
Quanto às tags de tira, você está melhor com uma biblioteca de filtro HTML real. Há tantas reviravoltas envolvidas com o HTML que você simplesmente não deve confiar em nada que você apenas faça uma vez e esqueça. As pessoas gastam tempo fazendo esses filtros HTML, então use seu trabalho a sua vantagem.
Quanto a "direto para o banco de dados", bem em parâmetros vinculados, com certeza, isso é ótimo. Você pode colocar qualquer coisa com segurança em um parâmetro encadernado. Em uma string com cotações, espero que você esteja escapando do resultado.
Escape todos os caracteres ao colocá -lo no banco de dados. Ao recuperar e exibir, certifique -se de escapar da formação de HTML, como <sometag>
Portanto, ele é exibido em vez de ser tratado como código.
O PHP tem funções de saneamento pouco conhecidas, mas poderosas. Eu recomendaria usá -los: