Jump to content

Recommended Posts

Posted

Boas...

Ando a fazer um site para uma loja e estou a fazer um sistema de login. o sistema já está a funcionar bem, mas gostava de saber se tem algum problema de segurança, pois é uma das minhas preocupações.

//recebe a página escolhida pelo utilizador
$pagina = $_GET['pagina'];

//Recebe os dados do login
$username= $_POST['username'];
$password= $_POST['password'];
//recebe o tempo actual
$time=time();

//Define os parâmetros da sessão
$tempo = 1600;  //tempo da sessão em segundos
session_set_cookie_params($tempo, "/");
session_name("Loja");
session_start();

if ($pagina=="logout"){
	session_unset();
	session_destroy();
	include'pages/inicio.php';
}


//Verifica se os dados do login estão correctos
if ($username && $password) { 
	$password = md5($password);
	$consulta = "select * from users where nome='$username' and password='$password'";
	$result = mysql_query($consulta, $conexao);

	$rows = mysql_num_rows($result);
	if ($rows == 1)
	{
  			$_SESSION['username']=$username;
	}
	else{
		$login_error = true;
	}
}code]

Este código guarda o nome do utilizador numa variavel de sessão, não seria melhor guardar somente a ID da sessão e guardar o utilizador a que corresponde este id numa tabela da base de dados?

Alguém me pode dizer como posso melhorar a segurança deste pequeno script?

Obrigado
Posted

1º Esse md5 não está ai a fazer nada.

2º Validar os dados para não sofrer com um SQL Injection.

Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Posted

1º Esse md5 não está ai a fazer nada.

2º Validar os dados para não sofrer com um SQL Injection.

1º Esse md5 é necessário ali porque a password já está encriptada na base de dados, e para poder comparar preciso de encriptar a password que recebi do formulário de login.

2º Validar os dados? Como? Não percebi muito bem

Posted

Imagina que o user introduz o $username vaiporcima'#

Se a BD for MySQL qual é o resultado?

Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Posted

Pode estar activo as Magic Quotes, ou não!

Na minha opinião estragam mais do que ajudam. Mas é uma hipotese para quem não pretende fazer mais nada.

Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Posted

Bem, 1º o md5 é preciso e está correctamente aplicado!

Falta apenas fazeres, como o shunny disse, o escape a mysql injections. Usa o mysql_real_escape_string();

Eu uso esta função que vi no php.net:

//Evita o mysql injection
function escape($value) {
   // Stripslashes
   if (get_magic_quotes_gpc()) {
       $value = stripslashes($value);
   }
   
   // Quote if not a number or a numeric string
   if (!is_numeric($value)) {
       $value = "'" . mysql_real_escape_string($value) . "'";
   }
   
   return $value;
}
Posted

Campos que serão colocados na BD e que posteriormente serão apresentados na página também têm de ser validados contra HTML e JavaScript. Não faço ideia se o get_magic_quotes_gpc faz isso.

Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Posted

@shumy

Acho que estas a falar de XSS se for isso então esse código resolve...

<?php

function xss_protect( $data ) {

  $desinfectar = array('');
  $Limpo = array();

  $XSS = array( '/<[^>]*script*\"?[^>]*>/i', '/<[^>]*object*\"?[^>]*>/i',
               '/<[^>]*iframe*\"?[^>]*>/i', '/<[^>]*applet*\"?[^>]*>/i',
               '/<[^>]*meta*\"?[^>]*>/i', '/<[^>]*style*\"?[^>]*>/i',
               '/<[^>]*form*\"?[^>]*>/i' );

  $Limpar = preg_replace( $XSS , $desinfectar, $data );
  array_push( $Limpo, $Limpar );

return $Limpo[0];
}

echo xss_protect( $_REQUEST['varN'] ); //$_POST, $_GET, $_COOKIE...

?>
Posted

Bem, 1º o md5 é preciso e está correctamente aplicado!

Falta apenas fazeres, como o shunny disse, o escape a mysql injections. Usa o mysql_real_escape_string();

Eu uso esta função que vi no php.net:

//Evita o mysql injection
function escape($value) {
   // Stripslashes
   if (get_magic_quotes_gpc()) {
       $value = stripslashes($value);
   }
   
   // Quote if not a number or a numeric string
   if (!is_numeric($value)) {
       $value = "'" . mysql_real_escape_string($value) . "'";
   }
   
   return $value;
}

Estive a pesquisar sobre MySQL injection e resolvi aplicar a função que o Bruno colocou. Quanto a isso já está protegido. Obrigado

Agora a minha dúvida está na seguinte linha:

$_SESSION['username']=$username;

Eu guardo o username na sessão. Não seria guardar apenas um ID na sessão e o username numa tabela da BD que guarda os utilizadores online? Ou não faz diferenças a nível de segurança?

  • 2 weeks later...
Posted

Depois de fazer o sistema todo com a vossa ajuda apareceu-me outro problema. Eu tenho uma função que serve para validar se o utilizador é administrador ou não, e se este não for administrador redirecciona-o para a página index.php.

function validar($us)
{
	//Verifica se o utilizador que está a aceder a uma página privada é administrador ou não
	//Se o utilizador não for administrador ou não estiver registado, é redireccionado para a página index.php

	$consulta = "Select * from users where nome = '$us' and nivel='1'";
	$result = mysql_query($consulta, $conexao);

	if(mysql_num_rows($result)==0){
		header("Location: index.php");
	}
}

Mas esta função dá-me o seguinte erro:

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in C:\Programas\xampp\htdocs\projecto\admin.php on line 19

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in C:\Programas\xampp\htdocs\projecto\admin.php on line 21

Warning: Cannot modify header information - headers already sent by (output started at C:\Programas\xampp\htdocs\projecto\admin.php:19) in C:\Programas\xampp\htdocs\projecto\admin.php on line 22

Mas o que é mais estúpido é que se eu meter o código que está dentro da função, fora da função já não dá erro nenhum e funciona na perfeição.

Alguém me explica qual é o problema?

Posted

Verifica qual é o conteudo dessa $conexao.

A variavel $conexao é o resultado da conexão ao servidor mysql.

//conectar ao servidor MySQL
$conexao = mysql_connect("localhost","teste","teste");
if (!$conexao) {
   	die('Erro de conexão: ' . mysql_error());
}

//escolhe a base de dados
mysql_select_db("loja",$conexao);

Porque é que este código só dá warning se estiver dentro da função?

Posted

OK, eu sei. Mas essa variavel provavelmente tem local scope, e não tem o link de ligação MySql

Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Posted

OK, eu sei. Mas essa variavel provavelmente tem local scope, e não tem o link de ligação MySql

Pois, deve ser esse o problema. Não sabia que o PHP era diferente neste pormenor. Para resolver o problema é só adicionar esta linha dentro da função?

global $conexao;

Ou é preferível passar a variável por referência?

Posted

Eu em geral não gosto de variaveis globais. Não que dizer que não possam existir excepções.

Neste caso até nem parece mal ser global. Mas se estiveres a programar no paradigma OOP, é preferivel ser uma variavel da classe. Ou melhor...  ter uma classe que te prepara a conexão e trata os erros.

Aqui há coisa de 2 anos fazia umas malhas de croché, depois fartei-me e fui para informática!

Posted

Boas,

Para não estar a abrir um novo tópico, vou escrever a minha dúvida já aqui. Neste momento tenho um formulário com a seguinte estrutura:

<form action="login.php" id="login" name="login">
  <input type="text" name="username" id="username">
  <div class="nav-body-login">Password:</div>
  <div id="form2">
  <input type="password" id="password" name="password">
  </div>
  <div id="submit_form">
  <input type="submit" id="submit" name="submit" value="Login">
</form>

E o ficheiro que valida o formulário é o ficheiro login.php, com o seguinte código:

<?php

//Evita o mysql injection
function escape($value) 
{
// Stripslashes
if (get_magic_quotes_gpc()) 
{
	$value = stripslashes($value);
}
// Quote if not a number or a numeric string
if (!is_numeric($value)) 
{
	$value = "'" . mysql_real_escape_string($value) . "'";
}

	return $value;
}

session_start();

$time = time();

error_reporting(E_ALL);
$script_base = dirname($_SERVER['SCRIPT_FILENAME']);  //define o root do ficheiro...
define('SCRIPT_BASE', $script_base);

include SCRIPT_BASE.'/includes/mysql.class.php';
include 'config.php';		//inclui o ficheiro de instalacao

$ligacao = new MySQL_DB_Connector; //faz a ligacao a classe que esta no ficheiro mysql.class.php
$ligacao->connect($host, $username, $password); //os valores $host, $username e $password estão no ficheiro config.php
mysql_select_db($database) or die("ERRO: Impossível escolher a base de dados: ".mysql_error());

if(isset($username) and isset($password)) //se tiverem sido introduzidos password e username...
{
$username = $_POST['username'];
$password = $_POST['password'];
//escape($password); //faz uso da função que escrevi acima, que evita o mysql injection
//$password = md5($password); //encripta a password
$query = "SELECT * FROM utilizador WHERE nome = '$username' AND password = '$password'";
$resultado = mysql_query ($query);

$array = mysql_fetch_array($resultado, MYSQL_ASSOC);

$id = $array["id"];
$email = $array["email"];
$permissao = $array["permissao"];

$rows = mysql_num_rows($resultado);

if($rows == 1) //se devolver resultado...
{
	$_SESSION['username'] = $username;
	$_SESSION['password'] = $password;
	$_SESSION['id'] = $id;
	$_SESSION['email'] = $email;
	$_SESSION['permissao'] = $permissao;
	?><script language="JavaScript">
			window.location = "admin/admin.php";
			</script><?php
}
if($rows == 0)
{
	?>
	<script language="JavaScript">
			window.location = "index.php";
			</script>
	<?php
	$erro = array();
	$erro [] = 'Impossivel fazer login !';
	return $erro;
}
}

?>

Ando aqui às voltas e ainda não consegui detectar qual o erro que está a fazer com que a página volte sempre ao index.php.

Alguém me pode ajudar?  😛

Posted

Tenta passar

if($rows == 1) //se devolver resultado...

para:

if($rows != 0) //se devolver resultado...

Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Posted

Tenta passar

if($rows == 1) //se devolver resultado...

para:

if($rows != 0) //se devolver resultado...

Continua a não dar. Mais uma vez, verifiquei se os dados que estava a introduzir no form eram os mesmos que estão na tabela e estes realmente correspondem. Não percebo, portanto, de onde provém este problema.  😛

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.