Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Wilian Fiabani

Segurança em PHP

Recommended Posts

Atualmente como informei eu uso expressões para cada tipo de dados passado seja ele $_Post, $_get, $_request etc....

 

{
	$string = str_replace("--", '*', $string);
	return $string;
}


function checa($a) {
	foreach ($_GET as $a)
	{
		if (eregi("[^a-zA-Z0-9_!=?&-]",$a))
		{
			return $a;
		}
	}

	foreach ($_POST as $a)
	{
		if (eregi("[^a-zA-Z0-9_-]",$a))
		{
			return $a;
		}
	}
}

$teste = sub_url($_SERVER['REQUEST_URI']);

if(!checa($teste)) 
{
	// Aqui ele para de executar.
} else {
	// Apartir daqui começa meus scripts
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Realmente!Totalmente sem lógica a função.

Pede um parâmetro de que nada vale...

Procura qualquer caracter não alfanúmerico.

Se achar,retorna o valor (cof cof...cadê a proteção mesmo?)

Lembrando que eregi e ereg serão deprecateds no PHP6.

Não seria mais algo como:

protecao.fnc.php:

<?php
public function checa($sg, $regex = '/[^a-z0-9]/i', $fnc = 'die', $mensagem = 'Caracteres não permitidos foram informados'){
	foreach($sg as $valor){
		if(preg_match($regex, $valor)){
			call_user_func($fnc, $mensagem);
		}
	}
}

checa($_REQUEST);
checa($_POST);
checa($_GET);
checa($_COOKIE);
?>

Não fiz para ficar bonito não!Só para corrigir e complementar mesmo...depois faço uma classe legalzinha (apesar de aqui já ter exemplos mó legais).

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sobre a utilização dos dados no banco, realmente estará corrompido, já no php você pode suar a função html_entity_decode()

 

abraços

mas aí que está a questão..

 

se o dado ficar diferente do original no banco de dados pode ocasionar diversos erros

 

por exemplo

 

imagine uma tabela de nome de clientes

 

vamos supor os nomes

 

 

Simões

Simélia

 

no banco de dados

será gravado

 

Simões

Simélia

 

se puxar os dados em ordem alfabética "ODER BY nome ASC"

 

o nome Simões vai vir antes de Simélia por causa do caracter "&"

 

por isso não é aconselhável converter os caracters originais.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal, essa dá p/ dizer q é facil de mais, mas vamos lá....

 

como filtrar os dados recebidos de um formulário?

 

ou seja, você recebe do user uma string qualquer e remove tudo o que for indesejado, como (', ", <script>), só aceitando caracteres maiusculos, minusculos e numeros.

 

o usuário envia: ' or 1='1

e você devolde: or11

 

entenderam?

 

eu já fiz o meu aqui, no final eu mostro.

 

Hei !!!

 

 

Kara, acabei de escrever, tenta ai:

 

function getSecureRequest( $fields = null ){
		$ret = array();
		
		if ( is_array( $fields ) ){
			for ( $i = 0 , $t = count( $fields ); $i < $t; $i++ ){
				if ( isset( $_REQUEST[ $fields[ $i ] ] ) ){
					$matches = array();
		
					preg_match_all( "/\\w*[0-9]*/" , $_REQUEST[ $fields[ $i ] ] , $matches );
					
					$ret[ $fields[ $i ] ] = implode( "" , $matches[ 0 ] );
				}
			}
		} else {
			foreach ( $_REQUEST as $n => $v ){
				$matches = array();
		
				preg_match_all( "/\\w*[0-9]*/" , $v , $matches );
					
				$ret[ $n ] = implode( "" , $matches[ 0 ] );
			}
		}
		
		return( $ret );
	}
	
	$data = getSecureRequest( array( "id" , "name" ) );
	
	print_r( $data );

O parametro fields pode ser vazio ou uma matriz:

 

Se for vazio então ele vai pegar todos os $_GET e todos os $_POST e te devolver uma matriz com os dados tratados.

Se for uma matriz então ele vai procurar nos $_GET e nos $_POST os itens desejados e te devolver uma matriz com os dados tratados.

 

[]'s

João Neto

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal, essa dá p/ dizer q é facil de mais, mas vamos lá....

 

como filtrar os dados recebidos de um formulário?

 

ou seja, você recebe do user uma string qualquer e remove tudo o que for indesejado, como (', ", <script>), só aceitando caracteres maiusculos, minusculos e numeros.

 

o usuário envia: ' or 1='1

e você devolde: or11

 

entenderam?

 

eu já fiz o meu aqui, no final eu mostro.

function secureRequest(array &$request, $regex = '/[^a-z0-9]+/'){
	reset($request);
	while(current($request)){
		 $request[key($request)] = preg_replace($regex, '', strip_tags(current($request)));
		 next($request);
	 }
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Creio que o certo e fazer que nem maioria dos forums aceitar qualquer caracteres mas tratalos, tipo este aqui você posta aspas script qualquer coisa ele trata o mesmo seria uma boa forma assim não atrapalhando resultado final.

 

Obs: Alguem sabe como forum faz isto?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigão, preste atenção nos tópicos acima que você irá ter vários exemplos de filtro.

 

Renato Siroma, só o htmlentities não adianta, é preciso um tratamento mais eficiente, saca ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caros amigos,

 

Proteção é um assunto importante e controverso, portanto, as soluções muito simples nem sempre produzem um resultado satisfatório.

 

Eu tb procuro soluções práticas para combater o SQL Injection sem perder o conteúdo enviado pelo verdadeiro usuário (também conhecido como o rei ou cliente...rsrsr).

 

A minha idéia pega um pouco das idéias já aqui apresentadas. Seria o seguinte:

 

 

1º Usar htmlentities para que o usuário possa digitar ( " ' ´ ` ) (< >) sem restrições e de forma segura, já que os referidos caracteres são substituídos por uma referência.

Esta medida minimiza a possibiildade de inserção de código jscript, php, html - o que já uma boa coisa.

 

2º Usar str_ireplace (que processa as expressões quer sejam maiúsculas ou não) para substituir expressões perigosas como SELECT, DROP TABLE, #, etc. por uma representação dela, tipo: SELECT seria substituida por ELEC[T], DROP por [D]RO[P]. Aí não perderíamos o conteúdo.

 

 

Desta forma, inviabilizaríamos inserção de SCRIPTS (jscript, php) e códigos SQL.

 

 

Deu pra entender? o que acham?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou aqui para aprender e compartilhar conhecimentos, por isso, estejam à vontade pra criticar, descartar ou melhorar o código.

Um exemplo completo (html + php) seria o seguinte:

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Untitled Document</title>

</head>

 

<body>

<form action="testes.php" method="post">

E-mail: <input id="email" name="email" type="text" />

Código: <input id="codigo" name="codigo" type="text" />

Nome: <input id="nome" name="nome" type="text" />

Aceita? <input type="checkbox" name="box" />

<input type="submit" value=" Ok! " />

 

</form>

 

<?php

 

function filtraInput( $string )

{

$string = trim( $string );

 

$string = str_ireplace( "content-type:", "[c]ontent-typ[e]:", $string );

 

$string = str_ireplace( "from:", "[f]ro[m:]", $string );

 

$string = str_ireplace( "bcc:", "c[c:]", $string );

 

$string = str_ireplace( "to:", "[t][o:]", $string );

 

$string = str_ireplace( "autoreply:", "[a]utorepl[y:]", $string );

 

$string = str_ireplace( "insert", "nser[t]", $string );

 

$string = str_ireplace( "select", "elec[t]", $string );

 

$string = str_ireplace( "where", "[w]her[e]", $string );

 

$string = str_ireplace( "delete", "[d]elet[e]", $string );

 

$string = str_ireplace( "create", "[c]reat[e]", $string );

 

$string = str_ireplace( "where", "[w]her[e]", $string );

 

$string = str_ireplace( "drop", "[d]ro[p]", $string );

 

$string = str_ireplace( "table", "[t]abl[e]", $string );

 

$string = str_replace( "#", "[\#]", $string );

 

$string = str_replace( "=", "[\=]", $string );

 

$string = str_replace( "--", "[\-\-]", $string );

 

$string = str_replace( ";", "[\;]", $string );

 

$string = str_replace( "*", "[\*]", $string );

 

$string = htmlentities( $string );

 

return $string;

}

 

 

// A função restauraInput só deve ser usada para imprimir, não pra consultar

function restauraInput( $string )

{

$string = trim( $string );

$string = str_ireplace( "[c]ontent-typ[e]:", "content-type:", $string );

$string = str_ireplace( "[f]ro[m]", "from", $string );

$string = str_ireplace( "c[c:]", "bcc:", $string );

$string = str_ireplace( "[t][o:]", "to:", $string );

$string = str_ireplace( "[a]utorepl[y:]", "autoreply:", $string );

$string = str_ireplace( "nser[t]", "insert", $string );

$string = str_ireplace( "[w]her[e]", "where", $string );

$string = str_ireplace( "[d]elet[e]", "delete", $string );

$string = str_ireplace( "[c]reat[e]", "create", $string );

$string = str_ireplace( "[w]her[e]", "where", $string );

$string = str_ireplace( "[d]ro[p]", "drop", $string );

$string = str_ireplace( "[t]abl[e]", "table", $string );

$string = str_replace( "[\#]", "#", $string );

$string = str_replace( "[\=]", "=", $string );

$string = str_replace( "[\-\-]", "--", $string );

$string = str_replace( "[\;]", ";", $string );

$string = str_replace( "[\*]", "*", $string );

 

return $string;

}

 

 

//pego o nome do campo

foreach( $_POST as $nomeCampo => $valorCampo )

{

$_POST[ $nomeCampo ] = filtraInput( $valorCampo );

print( "$nomeCampo = " . $_POST[ $nomeCampo ] . "<br />" );

print( "$nomeCampo (restaurada) = " . restauraInput( $_POST[ $nomeCampo ] ) . "<br />" );

}

 

?>

</body>

</html>

Compartilhar este post


Link para o post
Compartilhar em outros sites

mantenho posição de que tudo que fazem é desnecessário

 

basta usar addslashes

 

sempre comento algo do tipo

 

"basta evitar que a injeção penetre, não precisa se preocupar com o conteúdo da seringa"

Compartilhar este post


Link para o post
Compartilhar em outros sites

mantenho posição de que tudo que fazem é desnecessário

 

basta usar addslashes

 

sempre comento algo do tipo

 

"basta evitar que a injeção penetre, não precisa se preocupar com o conteúdo da seringa"

 

Hinom, tire-me uma dúvida. O addslashes impede que um inavsor envie a expressão or 1=1;drop table ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como o hinom disse, basta escapar as aspas :rolleyes:

 

http://br2.php.net/manual/pt_BR/function.m...cape-string.php

 

e tratar os caracteres que você não deseja em sua aplicação caso queira http://forum.imasters.com.br/public/style_emoticons/default/assobiando.gif

 

http://www.php.net/preg_replace

 

do resto é bobagem tipo [a-z][0-9] htmlentities

 

Ex.:

Moro na cidade de 'Cuiabá' o meu numero é (65) 0000-0000, se o usuário digitou assim porque não mantê-lo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

é preciso entender o qué a tal "injeção"

 

um exemplo prático, montando uma query com php

 

$sql = "SELECT * FROM tabela WHERE ID = ' " . $id . " '";

supondo-se $id = 1

 

a query seria

 

SELECT * FROM tabela WHERE ID = '1'

o banco de dados executará exatamente o que foi enviado

 

as injeções são simples truques onde é feito um "corte" na query

 

usando a query acima como exemplo.

se o invasor souber o nome da tabela, bastaria enviar o valor de $id assim

1'; DROP TABLE noticia; --

veja como a query SQL será enviada para o servidor:

 

SELECT * FROM noticia WHERE ID = '1'; DROP TABLE noticia; --'
a primeira parte será executada

SELECT * FROM noticia WHERE ID = '1';
OK, sem problema

mas... há uma segunda query..

 

DROP TABLE noticia

que nesse caso, excluirá a tabela "noticia" por completo

 

; termina uma linha SQL

portanto, após ; é possível criar uma nova query

 

no final, "--" siginifica que deve ignorar tudo que existir após a query.

 

isso só é possível se o programa que monta a query permitir a injeção das singles quotes (aspas simples), que estão sendo usadas nesse caso para formação das querys SQL

 

o que acontece se escapar das singles quotes ?

 

SELECT * FROM noticia WHERE ID = '1\'; DROP TABLE noticia; --'

a query não será terminada, pois não reconhecerá \' como terminação da primeira single quote aberta, portanto, o valor de $id será interpretado por completo

 

o banco de dados procurá pelo ID cujo valor seja exatamente igual a "1'; DROP TABLE noticia; --"

 

obviamente que não vai existir e tampouco executará a consulta pois contém caracteres não numéricos. (isso depende da definição do tipo de dados da coluna em questão)

nesse caso, o servidor retornará mensagem de erro .

 

a mensagem de erro real do server deve ser ocultada do usuario final mas deve ser gravada em log interno para que o programador consulte e faça as devidas correções ou estatísticas sobre lgos de erros

 

esse assunto é abordado há mais de 10 anos e muitos continuam complicando e criando um monstro de 7 cabeças.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá pessoal,

 

Muito bom este tópico de vocês.

 

Estava lendo no site do Php sobre como evitar SQL Injection e teve um comentário dizendo que uma forma simples contra isso é converter as entradas em binários, para cada caracter digitado você o modifica e insere no seu db de forma filtrada, depois é só reconvertê-lo novamente quando buscá-lo do banco de dados.

 

E isso evita o que o pessoal falou sobre os dados virem invertidos nas chamadas ao banco de dados ORDER BY ASC, tendo usado a função htmlentites.

 

I think that easy way to protect against SQL injection is to convert inputted data into binary format, so that whatever input is, in sql query it will consist only of 1s and 0s.

Abaixo um link para uma tabela ASCCII e Binário.

 

http://www.spectrum.eti.br/news/tabela_ascii_completa

 

Comentários?

Compartilhar este post


Link para o post
Compartilhar em outros sites

$q = _POST['q'];

try {

if(preg_match("/[^\sa-zA-Z0-9]/i", $q){

throw new Exception("SQLInjection");

}

catch (Exception $err){

if($err=="SQLInjection"){

registerSqlAttack();

die("SQL Injection Detectado");

}

}

 

 

Pessoal, essa dá p/ dizer q é facil de mais, mas vamos lá....

 

como filtrar os dados recebidos de um formulário?

 

ou seja, você recebe do user uma string qualquer e remove tudo o que for indesejado, como (', ", <script>), só aceitando caracteres maiusculos, minusculos e numeros.

 

o usuário envia: ' or 1='1

e você devolde: or11

 

entenderam?

 

eu já fiz o meu aqui, no final eu mostro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Raul,

 

só uma pergunta

 

e se precisar gravar no banco o valor

' or 1='1
exatamente como foi digitado ?

 

no caso desse forum, por exemplo,

já pensou se o forum bloqueasse e gravasse

or1=1
?

 

Por isso, não faz sentido nenhum substituir caracteres.

Basta escapar das single quotes.

 

A não ser que num caso especíico e tão somente para esse caso em específico realmente necessite fazer esse tipo de filtragem.

Caso contrário, o que está fazendo é corrompimento de dados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.