Principais erros de segurança em códigos PHP
- Nunca executar consultas não-escapadas
O PHP tem uma propriedade, ativa por default, que automaticamente escapa (adicionando uma contrabarra antes de) certos caracteres que vierem de um GET, POST, ou COOKIE.
A aspa simples (') é um exemplo de um character que é escapado automaticamente. Isto é feito de assim que você incluir variáveis de entrada em suas consultas SQL, e ele não irá tratar aspas simples como parte da consulta. Diga a seu usuário para entrar com <span class="var">$name</span> de um formulário e você performar esta consulta:
Normalmente, se for digitado $name com aspas simples, elas serão escapadas, então o MySQL poderá ver assim:
Fazendo com que a aspa simples dentro de "Joe's" não interfira com a sintaxe da consulta. Em algumas situações, você pode usar stripslashes() em uma variável de entrada.
Se você colocar a variável dentro de uma consulta, certifique-se de usar addslashes() ou mysql_escape_string() para escapar as aspas simples antes de executar a consulta. Imagine se uma consulta não escapada passar, e um usuário malicioso tiver entrado parte de uma consulta com seu nome!?
No formulário de entrada, o usuário pode ter entrado: Joe',Admin='1
Como seu nome, e desde que aspas simples não foram escapadas, ele/ela serão capazes de verdadeiramente terminar a definição do nome, colocando uma virgula, e ajustando uma outra variável chamada Admin!
A consulta final com se parecerá como esta:
Em algumas configurações, magic_quotes_gpc (a propriedade que automaticamente colocar barras em todos as entradas) está ajustado em OFF. Você pode utilizar a função get_magic_quotes_gpc() para verificar seu estado (ela retorna verdadeiro ou falso). Se retornar falso, simplesmente use addslashes() para colocar barras em todas as entradas (é mais fácil se você usar $_POST, $_GET, e $_COOKIE ou $HTTP_POST_VARS, $HTTP_GET_VARS, e $HTTP_COOKIE_VARS, ao invés das globais porque você poderá percorrer estes vetores usando um loop foreach() e adicioanar barras a cada um deles).
O PHP tem uma propriedade, ativa por default, que automaticamente escapa (adicionando uma contrabarra antes de) certos caracteres que vierem de um GET, POST, ou COOKIE.
A aspa simples (') é um exemplo de um character que é escapado automaticamente. Isto é feito de assim que você incluir variáveis de entrada em suas consultas SQL, e ele não irá tratar aspas simples como parte da consulta. Diga a seu usuário para entrar com <span class="var">$name</span> de um formulário e você performar esta consulta:
UPDATE users SET Name='$name' WHERE ID=1;
Normalmente, se for digitado $name com aspas simples, elas serão escapadas, então o MySQL poderá ver assim:
UPDATE users SET Name='Joe\'s' WHERE ID=1;
Fazendo com que a aspa simples dentro de "Joe's" não interfira com a sintaxe da consulta. Em algumas situações, você pode usar stripslashes() em uma variável de entrada.
Se você colocar a variável dentro de uma consulta, certifique-se de usar addslashes() ou mysql_escape_string() para escapar as aspas simples antes de executar a consulta. Imagine se uma consulta não escapada passar, e um usuário malicioso tiver entrado parte de uma consulta com seu nome!?
UPDATE users SET Name='Joe\'s',Admin='1' WHERE ID=1;
No formulário de entrada, o usuário pode ter entrado: Joe',Admin='1
Como seu nome, e desde que aspas simples não foram escapadas, ele/ela serão capazes de verdadeiramente terminar a definição do nome, colocando uma virgula, e ajustando uma outra variável chamada Admin!
A consulta final com se parecerá como esta:
UPDATE users SET Name='Joe',Admin='1' WHERE ID=1;
Em algumas configurações, magic_quotes_gpc (a propriedade que automaticamente colocar barras em todos as entradas) está ajustado em OFF. Você pode utilizar a função get_magic_quotes_gpc() para verificar seu estado (ela retorna verdadeiro ou falso). Se retornar falso, simplesmente use addslashes() para colocar barras em todas as entradas (é mais fácil se você usar $_POST, $_GET, e $_COOKIE ou $HTTP_POST_VARS, $HTTP_GET_VARS, e $HTTP_COOKIE_VARS, ao invés das globais porque você poderá percorrer estes vetores usando um loop foreach() e adicioanar barras a cada um deles).
Parabéns pelo artigo! :-)
31/03/2011 2:13am
(~13 anos atrás)
Por incrível que pareça, já peguei muito código de programador experiente contento estes erros.
Muito bom o seu artigo.
As vezes até eu esqueço essas boas práticas.
Muito bom o seu artigo.
As vezes até eu esqueço essas boas práticas.
17/11/2008 4:36am
(~16 anos atrás)
a ta. Foi isso mesmo que a gente fez aqui. No config.inc.php tem uma autoload que já inclui classes comuns a do framework e instancia tbm classes comuns ao sistema.
Vlw ae... vou ver uma forma de passar isso de outro jeito... tem algum tempo que isso me incomoda de ficar na URL :)
Abcs
Vlw ae... vou ver uma forma de passar isso de outro jeito... tem algum tempo que isso me incomoda de ficar na URL :)
Abcs
13/11/2008 9:09am
(~16 anos atrás)
Isso depende de como está o código de verificação e de include.
O que desaconselho é usar variaveis que apontem para arquivos em um include pois um hacker pode fazer seu sistema apontar para um arquivo dele e dessa forma comprometer seu sistema.
A forma que os frameworks como cake, symfony, phpmvc, etc usam tem a ver com sessao (controller) e acao (metodo).
Dessa forma não tem que dar nenhum include.
Um sistema baseado em Orientação a Objetos a meu modo de ver tem que fazer uso de autoload e ter uma lista de classes válidas a serem instanciadas (disptatcher).
Quanto a estar certo ou errado é ponto de vista mas acho que vc ganharia em segurança se não utiliza-se include por parâmetros via URL.
O que desaconselho é usar variaveis que apontem para arquivos em um include pois um hacker pode fazer seu sistema apontar para um arquivo dele e dessa forma comprometer seu sistema.
A forma que os frameworks como cake, symfony, phpmvc, etc usam tem a ver com sessao (controller) e acao (metodo).
Dessa forma não tem que dar nenhum include.
Um sistema baseado em Orientação a Objetos a meu modo de ver tem que fazer uso de autoload e ter uma lista de classes válidas a serem instanciadas (disptatcher).
Quanto a estar certo ou errado é ponto de vista mas acho que vc ganharia em segurança se não utiliza-se include por parâmetros via URL.
13/11/2008 8:38am
(~16 anos atrás)
Marcos, não entendi o lance que vc falou dos frameworks...
Exemplo, aqui na empresa a gente criou um framework, que funciona mais ou menos do jeito que vc falou. Ex.:
URL:
www.sitetal.com.br/sistema/index.php?t=pedido&a=frm
o parâmetro "t" é o nome da pasta onde fica a página vindo pelo valor de a (ou seja, ele vai procurar se na pasta pedido, existe uma página chamada frm.php). Se tiver ele da o include vai na pasta de classes e instancia a classe class.PEDIDO.php...
Os métodos são chamados na própria página, conforme for preciso. A gente não passa método via URL.
Você acha que essa forma ta errada? Por que estaria? Como posso corrigir isso?
Exemplo, aqui na empresa a gente criou um framework, que funciona mais ou menos do jeito que vc falou. Ex.:
URL:
www.sitetal.com.br/sistema/index.php?t=pedido&a=frm
o parâmetro "t" é o nome da pasta onde fica a página vindo pelo valor de a (ou seja, ele vai procurar se na pasta pedido, existe uma página chamada frm.php). Se tiver ele da o include vai na pasta de classes e instancia a classe class.PEDIDO.php...
Os métodos são chamados na própria página, conforme for preciso. A gente não passa método via URL.
Você acha que essa forma ta errada? Por que estaria? Como posso corrigir isso?
13/11/2008 8:05am
(~16 anos atrás)
Essa sua preocupação tem sentido quando se usa eval() da forma como mencionei no artigo, pois eval executa uma string como código php.
No caso de SQL sim e é o que se chama de SQL injection.
No caso de SQL sim e é o que se chama de SQL injection.
04/11/2008 3:52am
(~16 anos atrás)
Existe por exemplo algum função que é executada mesmo sem eu chama-la??
exemplo se eu pego $_GET['nome'] e faço $nome = $_GET['nome']; e depois disso eu faço os tratamentos de segurança
ai o usuário malicioso digita funcao_maliciosa(); , ele vai guardar isso como uma string ou como uma função??
pq se acontece de $nome = funcao_maliciosa(); ai pode ser que ele consiga dados mas se gravar como string acho que nao faz diferença.
[Na verdade eu tenho quase certeza que isso nao é um problema mas é só pra tirar as dúvidas mesmo]
exemplo se eu pego $_GET['nome'] e faço $nome = $_GET['nome']; e depois disso eu faço os tratamentos de segurança
ai o usuário malicioso digita funcao_maliciosa(); , ele vai guardar isso como uma string ou como uma função??
pq se acontece de $nome = funcao_maliciosa(); ai pode ser que ele consiga dados mas se gravar como string acho que nao faz diferença.
[Na verdade eu tenho quase certeza que isso nao é um problema mas é só pra tirar as dúvidas mesmo]
03/11/2008 4:49pm
(~16 anos atrás)
outro tipo de falha muito comum é com upload de arquivos.
muitos sistemas nao fazem validação do tipo de arquivo enviado, permitindo que arquivos .php, por exemplo, sejam enviados
muitos sistemas nao fazem validação do tipo de arquivo enviado, permitindo que arquivos .php, por exemplo, sejam enviados
30/09/2008 1:27am
(~16 anos atrás)
O codigo javascript pode ser facil e util mas e haqueavel, e quando o meu pc ficou sem java, eu nao acessava os arquivos corretos, entao tive que baixar o FF. Eu recomendo a todos aqui a usarem o PHP, e logo farei outros tutoriais...
16/09/2008 5:51am
(~16 anos atrás)