Archive for category development

Encriptação de senhas no banco de dados

A não ser quando for uma requisição explícita por parte do cliente, uma boa prática de desenvolvimento é sempre encriptar senhas presentes no banco de dados.

Essa prática é interessante tanto para questões de segurança quanto de privacidade – afinal não há razões para que nem mesmo administradores tenham acesso às senhas utilizadas por quaisquer usuários.

Muitos desenvolvedores tem isso em mente, entretanto, porém os métodos usuais utilizados para fazer essa encriptação não é a mais adequada. Na maioria das vezes, em especial no mundo php, a função escolhida para fazê-la é a md5().

O problema de utilização do algoritmo MD5 para encriptação é somente um: ele não é um algoritmo de encriptação. Apesar de “ocultar” o conteúdo original de um texto, esse método foi concebido para ser uma função de hashing.

Ok, ele até dificulta que se descubra qual é o texto original. Porém, se você procurar no google, existe uma porção de páginas com listagens de senhas em MD5, assim como de dicas para desenvolvimento de ferramentas de brute force. O principal problema é que, para uma mesma string, o hash gerado é sempre o mesmo.

O que eu costumo fazer para salvar senhas encriptadas é utilizar a função crypt(). Vamos a um exemplo:

$senha = ’1234′;
$senhaCrypt = crypt($senha);

echo $senhaCrypt;

Execute o exemplo algumas vezes; percebe que cada vez que geramos a senha, a string gerada é diferente? Isso já é um excelente ponto para garantirmos a segurança.

Porém, como fazer para desencriptar a string, já que cada vez que ela é gerada temos um diferente resultado? Outro ponto forte, não há como. Para validarmos se a senha informada é igual a senha encriptada no banco, comparamos do seguinte modo:

$senha = ’1234′;
$senhaCrypt = crypt($senha);

// Ignoramos aqui qualquer tipo de validação
$senhaInput = $_POST['senha'];

if(crypt($senhaInput, $senhaCrypt) == $senhaCrypt))
{
echo ‘Senha válida’;
}
else
{
echo ‘Senha inválida’;
}

Note que para comparação das senhas, comparamos a senha encriptada com o resultado de crypt() novamente, porém utilizando como segundo parâmetro a própria senha encriptada.

Obviamente que o demonstrado aqui é um mero exemplo tosco, e precisa ser estendido para funcionar juntamente a um banco de dados e tudo o mais. Mas a idéia fica aí: utilizando-se crypt(), conseguimos um melhor nível de segurança e de privacidade.

Última dica: para guardar a senha encriptada no banco, utilize um campo texto (varchar, por exemplo) de tamanho 34 bytes – a chamada ao crypt() sempre gera uma string nesse tamanho.

Tags: ,

Trim() em javascript

A boa e velha função trim() é uma excelente pedida em qualquer linguagem, e chega a ser supreendente que javascript não a possua nativamente. Além de eliminar espaços em branco (assim como tabulações) de uma string, é também uma boa maneira pra se fazer algumas validações (como por exemplo verificar se um campo obrigatório não foi preenchido somente com espaços).

Já vi diversas implementações da função trim() – assim como de ltrim() e rtrim() – em javascript, mas acho que nenhuma tão elegante quanto a presente em http://www.somacon.com/p355.php.

String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, ”);
}

String.prototype.ltrim = function() {
return this.replace(/^\s+/, ”);
}

String.prototype.rtrim = function() {
return this.replace(/\s+$/, ”);
}

Utilizando-se de expressões regulares para fazer as substituições de espaços por vazio, o grande lance de elegância de código é utilizá-la como membro do protótipo do objeto String. Assim, basta chamar o método em qualquer váriavel do tipo String, como por exemplo variable.trim().

Ótima pedida para adicionar-se em um arquivo .js para incluir em todas as páginas.

Uma coisa que eu tentei rapidinho fazer e não consegui é adicionar ao protótipo de um objeto uma propriedade baseada em um método. Explico melhor por um exemplo: eu gostaria de adicionar uma propriedade booleana empty para realizar validação; a definiria baseada no resultado de trim(), algo mais ou menos como

String.prototype.empty = (this.trim().length == 0 ? true : false);

Criar a propriedade baseado em um valor é tranquilo (String.prototype.empty = false). Mas e baseado no resultado de uma função que foi definida no protótipo? Alguém sabe como?

Tags:

Loading, please wait…

Pra quem procura uma boa solução para fazer uma barra de carregamento em PHP, o site PHPBuilder.com publicou um artigo intitulado Displaying Dynamic Progress Bars.

Basicamente, o que o código faz é imprimir divs de tamanho diferentes, sempre na mesma posição absoluta, conforme o código atingir pontos chaves da execução, forçando a saída da resposta para o browser com a função flush().

É claro que a solução exige pelo menos que o desenvolvedor tenha uma base de quanto tempo irá durar o processamento, ou ao menos que identifique os pontos chaves de execução do código.

Para exercitar: ao invés de reenviar divs, que tal só enviar chamadas para uma função javascript que altere a largura do div que representa a porcentagem? Muito mais fácil caso queira-se eventualmente alterar o estilo das barras.

Tags:

Aventuras com ActionScript

Recentemente tive a oportunidade de trabalhar com programação em Flash, e posso dizer que me surpreendi com ActionScript 2.0. Mostrou-se uma linguagem muito mais elaborada do que eu imaginava, até porque a Macromedia já tinha feito cagadas homéricas quanto a linguagem – como por exemplo alterar sintaxe ou nome de métodos e propriedades.

Tá certo que faltam uma série de elementos, tal como métodos abstratos (esse particularmente me deu uma trabalheira pra resolver). E também alguns erros monstruosos e sem sentido, como esse tipo de erro abaixo:

**Error**

MyClass.as: Line 2: The name of this class, ‘MyClass’, conflicts with the name of another class that was loaded, ‘MyClass’.
{

Total ActionScript Errors: 1 Reported Errors: 1

Digamos que eu tenha um arquivo index.fla, e faça um import MyClass.as. Eventualmente, esse erro pode surgir. Procurei um monte por outra referência à classe e nada. Então resolvi perguntar ao google, e claro, ele me deu a solução.

Após muito procurar, encontrei que o problema é a data dos arquivos. Como assim as datas? Pois é, difícil de acreditar… Em certas situações, quando se gera um erro de compilação presente no arquivo .as, tal como acesso à uma propriedade inexistente, ou erro de sintaxe, esse erro pode surgir – preste atenção no pode.

Ao gerar esse erro, se a data de última alteração do .as for posterior a data do .fla, então a mensagem de conflito de classes pode surgir. A solução é bem simples: salve o .fla novamente antes de publicar o .swf. E pronto, tudo resolvido.

Só me resta uma dúvida: alguém pode me explicar por que esse erro ocorre?

Tags: ,

WordPress: caloroso primeiro contato

Desde que comecei a ler blogs mais voltados pra programação, tenho visto WordPress a rodo. Decidi então baixá-lo e fazer alguns testes. Testei em casa mesmo, depois de ter instalado o WAMP, e achei muito bacana. Ótimo então, lá vamos nós utilizá-los.

Instalei no servidor e recebi uma desagradável mensagem: You do not have sufficient permissions to access this page, com erro no arquivo capabilities.php.

Após algum tempo de pesquisa, encontrei a solução. Pelo que li, esse problema se aplica tanto pra instalalações novas quanto (principalmente) para upgrades de versão do WordPress.

Segue o conteúdo do arquivo wp-config.php:

// ** MySQL settings ** //
define(‘DB_NAME’, ‘*****’); // The name of the database
define(‘DB_USER’, ‘*****’); // Your MySQL username
define(‘DB_PASSWORD’, ‘*****’); // …and password
define(‘DB_HOST’, ‘*****’); // 99% chance you won’t need to change this value

// You can have multiple installations in one database if you give each a unique prefix
$table_prefix = ‘wp_’; // Only numbers, letters, and underscores please!

// Change this to localize WordPress. A corresponding MO file for the
// chosen language must be installed to wp-includes/languages.
// For example, install de.mo to wp-includes/languages and set WPLANG to ‘de’
// to enable German language support.
define (‘WPLANG’, ”);

/* FIX */
//define(‘DISABLE_CACHE’, true);
set_magic_quotes_runtime(0);
ini_set(‘magic_quotes_gpc’,0);

/* That’s all, stop editing! Happy blogging. */

define(‘ABSPATH’, dirname(__FILE__).’/');
require_once(ABSPATH.’wp-settings.php’);

Pra corrigir o problema, basta adicionar as linhas em negrito. O problema acontece porque a diretiva magic_quotes_runtime do php.ini do servidor de hospedagem está ativa. Logo, forçamos, de um modo global para o WordPress, com que essa diretiva seja desativada, corrigindo então o erro!

Quanto a desligar o magic_quotes_gpc, creio não ser necessário. Apenas desabilitando magic_quotes_runtime solucionou o problema na minha situação, mas por via das dúvidas, mantive-o desabilitado. Preciso dar uma olhadinha no código pra ver se a inclusão no banco de dados verifica anteriormente se magic_quotes_gpc está ativado ou não antes de ter certeza disso.

Em relação ao DISABLE_CACHE, que também foi sugerido que se desabilitasse, esse sim eu não acho boa idéia… Pelo menos não enquanto não surgirem novos problemas, afinal de contas, a realização de cache do output dá uma boa reduzida do tempo de carregamento da página.
Mais uma coisinha: adicionar as linhas depois de require_once(ABSPATH.’wp-settings.php’); não adianta. Havia testado isso anteriormente!

Tags: ,