Gerador de senha aleatória em PHP [UPDATE]

Continuando com a série de posts sobre PHP, segue um script que foi útil para o desenvolvimendo do novo And After.

Por questões de segurança a senha dos usuários ficam criptografadas no banco (MD5) e o processo é irreversível (pelo menos em teoria) – isso impede a recuperação delas e cria a necessidade de regerar uma senha aleatória caso o usuário esqueça a sua.

Baseado em em um script da webtoolkit fiz algumas alterações (insignificantes) para atender exatamente ao que eu precisava, abaixo segue a função generatePassword que recebe um único parâmetro ($length) que indica o tamanho do password gerado.

 

function generatePassword($length) {
  $vowels = "aeiouyAEIOUY";
  $consonants = "bdghjmnpqrstvzBDGHJLMNPQRSTVWXZ0123456789";
  $password = "";
  $alt = time() % 2;
  for ($i = 0; $i < $length; $i++) {
    if ($alt == 1) {
       $password .= $consonants[(rand() % strlen($consonants))];
       $alt = 0;
    } else {
       $password .= $vowels[(rand() % strlen($vowels))];
       $alt = 1;
    }
  }
  return $password;
}

O script tem 2 conjuntos de caracteres (nas variáveis vowels e consoants) e intercala um caractere randômico de um grupo com um caractere randômico de outro grupo até a string (nosso password) atingir o tamanho requisitado.

[update]

O Carlos André Ferrari comentou uma outra função, com menos código porém sem intercalar os grupos de caracteres (vogais e consoantes) para gerar a senha, porém igualmente funcional:

function generatePassword($length=6) {
	return substr(str_shuffle("aeiouyAEIOUYbdghjmnpqrstvzBDGHJLMNPQRSTVWXZ0123456789"), 0, $length);
}

[/update]

 

Se você quiser aumentar o nível de segurança pode inserir caracteres especiais em uma das variáveis da string usada…

Velocity – incluindo diversos arquivos através de um loop

O Chris já publicou aqui um tutorial de Velocity, uma linguagem de templates que estou usando diariamente no trabalho.

Como eu não conhecia a linguagem até começar a trabalhar aqui, existem várias coisas que são são novidades para mim – e os blogs e docmentações estão ajudando a aumentar a produtividade.

Para compartilhar o que aprendi (e servir para minhas consultas futuras), fiz algumas contribuições com posts aqui no O Desenvolvedor, e entre as relacionadas ao Velocity (e Java) destaco duas:

  1. Formatação de datas em Java
  2. Loop no Velocity com limite numérico (foreach)

 

Velocity – Loop de includes usando variáveis

Estava estudando métodos para dar include (parse) em arquivos com o Velocity, e em um caso específico queria incluir diversos arquivos através de um loop: código enxuto, ao invés de adicionar uma linha para cada parse.

Se você não sabe como funciona o parse no Velocity, veja este exemplo de código.

 

 

Para ilustrar este post, criei um "problema" e abaixo explico a solução.

 

Problema
Necessário fazer diversos includes a partir de uma lista de arquivos (string).

Solução
Pegar a lista, transformar em array e usar o parse para cada elemento do array

 

Supondo que você tem a string: "include1,include2,include5" e estes são os nomes de arquivos que você precisa incluir, o primeiro passo é dar um split pelas vírgulas e transformar isso em um array.

 

 

Primeiro setamos uma variável ($inc) com a lista de includes que serão feitos

#set($inc = "include3,include4,include9")

Abaixo utilizo o método split (ler documentação) na variável $inc gerada anteriormente, separado os elementos pela vírgula e criando um array com os nomes dos arquivos (o array poderia ser criado diretamente, porém usei o string para enriquecer mais o exemplo).

#set($arr = $stringUtils.split($inc,","))

Pronto, agora temos um array com o nome dos arquivos e é aqui que a "mágica" começa. Criamos um loop (foreach) para o array, e dentro dele definimos uma variável com o caminho do arquivo que será incluído e chamamos o parse para a variável do caminho ($dir).

#foreach($o in $arr)
   #set($dir = "includes/vm/"+$o+".vm")
   #parse($dir)
#end

 

Tentei concatenar o nome do arquivo (elemento do array) com o caminho direto na linha do parse e não funcionou. O workarround de definir a variável antes resolve o problema!

Espero que seja útil, esse script pode ser bastante útil para o controle de includes!

Criar atalhos no teclado com Javascript e jQuery

Depois de publicada a tabela de Key Codes para javascript vamos aprender algumas formas mais avançadas para criar atalhos de interface para sites utilizando o teclado.

O exemplo simples já foi dado no post da tabela de keycodes, fiz um exemplo um pouco mais complexo que permite verificar quando duas teclas estão pressionadas, para criar atalhos para por exemplo salvar um post que o usuário está escrevendo com o CTRL+S, ou permitir a um usuário da internet utilizar o CTRL+O para abrir um documento…

O exemplo abaixo não utiliza nenhuma biblioteca e comentei as linhas para facilitar o entendimento, segue o código:

var pressedCtrl = false;
//Quando uma tecla for liberada verifica se é o CTRL para notificar que CTRL não está pressionado
document.onkeyup=function(e){
	if(e.which == 17)
	pressedCtrl =false;
}
// Quando alguma tecla for pressionada:
// Primeiro if - verifica se é o CTRL e avisa que CTRL está pressionado
// Segundo if - verifica se a tecla é o "s" (keycode 83) para executar a ação
document.onkeydown=function(e){
	if(e.which == 17)
		pressedCtrl = true;
	if(e.which == 83 && pressedCtrl == true) {
		//Aqui vai o código e chamadas de funções para o ctrl+s
		alert("CTRL + S pressionados");
	}
}

No caso acima utilizei uma variável "pressedCtrl" que controla quando a tecla CTRL está pressionada e só se este caso for true ele executará as ações dos atalhos.

Com jQuery fica quase a mesma coisa – agora sem os comentários.

 

var pressedCtrl = false;
$(document).keyup(function (e) {
	if(e.which == 17)
		pressedCtrl=false;
})
$(document).keydown(function (e) {
	if(e.which == 17)
	pressedCtrl = true;
	if(e.which == 83 && pressedCtrl == true) {
		//Aqui vai o código e chamadas de funções para o ctrl+s
		alert("CTRL + S pressionados");
	}
});
 

Com os exemplos simples acima é possível incrementar atalhos mais complexos de mais do que 2 teclas, e outras combinações de teclas também.

Agora vamos a um exemplo de atalho de navegação, controlar a paginação de um site pelas teclas direita e esquerda do teclado.  O código abaixo utiliza a tecla da direita para redirecionar a página para a url do link <a> com id="next" e a tecla da esquerda para o link com id "prev".

$(document).ready(function(){
	$("document").keyUp(function(e){
		e.keyCode == 39;
		window.location = $("#next").atrr("href");
	});
	$("document").keyUp(function(e){
		e.keyCode == 37;
		window.location = $("#prev").atrr("href");
	});
});

 

Com um pouco de criatividade é possível aumentar a usabilidade do seu site utilizando estes atalhos – e para interface de intranets é possível melhorar bastante e além da usabilidade aumentar a produtiivdade dos usuários.

Referências

 

 

Segurança com PHP (slides)

Como o prometido, estou realmente estudando PHP e deixando o ASP, reflexo disso é uma mudança no conteúdo do O Desenvolvedor, que está ficando recheado de posts sobre PHP – com a ajuda do Chris e do Furst.

Depois dos slides sobre as Novidades do PHP 5, hoje trago mais slides, desta vez para falar de Segurança. Essa foi a apresentação do Rafael Jaques no Tchê Linux 2009.

 

A apresentação fala dos tipos de ataque mais comuns e apresenta soluções e boas práticas para elevar a segurança das aplicações desenvolvidas.

 

E para quem não conseguir ver a apresentação no SlideShare, segue a versão em texto:

 

  1. Construindo uma aplicação PHP à Prova de Balas
    • Rafael Jaques
    • TcheLinux – Porto Alegre – 14/11/09
    • “ Buscai primeiro o reino do Senhor e a sua justiça, e todas as demais coisas vos serão acrescentadas” (Mateus 6.33)
  2. Pauta
    • Um pouco sobre segurança
    • Conhecendo os meios de ataque
    • Outros tipos de ameaça
    • Mais alguns cuidados
    • Perguntas
  3. Um pouco sobre segurança 1
  4. O que é segurança?
    • Segurança baseia-se em três pontos:

    CONFIDENCIALIDADE INTEGRIDADE DISPONIBILIDADE

  5. O que é segurança? Não se iluda. Não existem aplicações 100% seguras. Não ouse dizer isso… Você poderá ter sérios problemas.
  6. O quão segura deve ser a sua aplicação? Você deve encontrar um equilíbrio entre a segurança e a usabilidade do seu sistema. Crie um sistema com pouca segurança e ele será invadido . Crie um sistema com muita segurança e ele será impossível de usar .
  7. O quão segura deve ser a sua aplicação? Evite investir esforços onde não é necessário. Sempre revise o que você projetou.
  8. Os custos que envolvem uma aplicação segura Aplicações seguras tendem a custar caro… Aplicações não seguras tendem a custar mais caro ainda…
  9. Os custos que envolvem uma aplicação segura
    • Maior tempo de projeto e pesquisa
    • Programação extendida
    • Testes mais minuciosos
    • Maior uso de hardware
    • Maior uso de banda
    • Treinamento de pessoal interno
    • Treinamento do usuário

    Entre os custos envolvidos no desenvolvimento da aplicação, temos os seguintes pontos:

  10. não sacrifique a usabilidade do projeto
  11. Conhecendo os meios de ataque 2
  12. Quais os tipos de ataque que posso sofrer?
    • XSS (Cross-site Scripting)
    • SQL Injection
    • Session Hijacking
    • Cookie Theft

    Existem diversos tipos de ataque através da internet. Eis alguns:

    • Brute Force
    • Rainbow Table
    • Password Sniffing
    • Entre outros…
  13. XSS Cross-site Scripting O que é? Injeção de código arbitrário em uma página. Como ocorre? Geralmente através de brechas em formulários onde os dados enviados ao servidor não são devidamente filtrados.
  14. XSS Cross-site Scripting Exemplo
  15. XSS Cross-site Scripting Exemplo
  16. XSS Cross-site Scripting Como evitar Existem funções prontas no PHP para filtrar strings. Utilizando-as, além de evitar um XSS, você garante que o usuário conseguirá expressar o que realmente intentou.
  17. XSS Cross-site Scripting Como evitar
    • Funções que você pode utilizar:
    • htmlspecialchars()
    • htmlentities()
    • filter_input()

    Leia mais sobre XSS: http://tinyurl.com/mais-sobre-xss

  18. SQL Injection O que é? Injeção de código SQL arbitrário dentro de uma consulta legítima. Como ocorre? Na maioria das vezes a injeção de código SQL se dá a partir de formulários não filtrados, em que os dados recebidos vão diretamente para dentro da consulta.
  19. SQL Injection Exemplo
  20. SQL Injection Exemplo 1" OR 1="1
  21. SQL Injection Exemplo fulano"# ou fulano" —
  22. SQL Injection Como evitar Novamente… Filtrando os dados enviados pelo usuário é possível evitar que seja injetado código dentro do seu SQL.
  23. SQL Injection Como evitar
    • Funções que você pode utilizar:
    • addslashes()
    • mysql_real_escape_string()

    Leia mais sobre XSS: http://tinyurl.com/mais-sobre-sql-injection

  24. Session Hijacking O que é? Quando o invasor obtém acesso à sessão de um usuário autenticado. Como ocorre? Sempre que os dados do cliente são armazenados em sessão é gerado um ID. Caso alguém o descubra, poderá navegar pelo site como se fosse o usuário real.
  25. Session Hijacking Atenção… Hoje, com as configurações padrão do PHP é bem pouco provável que você sofra um ataque de roubo de sessão no seu site. Para tanto você deve estar atento às seguintes configurações:
  26. Session Hijacking Atenção… session.use_cookies session.use_only_cookies
  27. Session Hijacking Exemplo algumapagina.php?PHPSESSID=1234
  28. Session Hijacking Como evitar Nunca confie 100% no ID de sessão recebido. Você pode fazer algumas verificações redudantes, como comparar o IP e o User-Agent. Em casos mais vitais você pode sugerir ao usuário que utilize cookies, intruindo-o e falando da sua importância para uma navegação mais segura no site. Leia mais sobre Sess. Hijacking: http://tinyurl.com/mais-sobre-sess-hijacking
  29. Cookie Theft O que é? A tradução literal é “Roubo de Cookie”. Na verdade a literal mesmo é “Roubo de Biscoito”. 😛 Trata-se capturar cookies na máquina da vítima e utilizá-los para acessar o local desejado. Como ocorre? O roubo de cookie pode possuir duas naturezas: XSS e vulnerabilidades no próprio browser.
  30. Cookie Theft Como evitar O script que foi apresentado anteriormente no exemplo de XSS é responsável por roubar um cookie. Atualmente não são muito comuns falhas de browsers que permitam o roubo de cookies, mas no passado houveram muitos .
  31. Cookie Theft Como evitar No site do PHP Security Consortium [1] você pode consultar o resumo da newsletter da SecurityFocus [2], que possui sempre anúncio de novas vulnerabilidades encontradas. A partir disso você pode conscientizar os seus usuários caso perceba que os mesmos utilizem um browser vulnerável. [1] http://phpsec.org/projects/vulnerabilities/securityfocus.html [2] http://securityfocus.com/vulnerabilities
  32. Brute Force Attack O que é? O ataque por força bruta baseia-se na busca exaustiva da informação procurada, através de tentativa e erro com todas as possibilidades existentes. Como ocorre? O usuário mal intencionado acessa o formulário no qual irá tentar o ataque e utiliza um programa, estipulando uma cadeia de caracteres e um tamanho máximo para a frase. O programa irá tentar todas as combinações possíveis até que uma dê certo.
  33. Brute Force Attack Atenção… Este tipo de ataque é bastante semelhante ao Ataque de Dicionário . A diferença é que o dicionário esgota suas possibilidades mais rápido utilizando apenas palavras existentes e senhas comuns.
  34. Brute Force Attack Como evitar Existem dois meios bastante comuns de evitar este tipo de ataque: limite de tentativas e limite de tempo entre uma tentativa e outra. Leia mais sobre Sess. Hijacking: http://tinyurl.com/mais-sobre-brute-force
  35. Rainbow Table O que é? Semelhante ao ataque de força bruta, porém diretamente a um hash (md5, sha1, etc). Como ocorre? É a mistura de um ataque de força bruta com um ataque de dicionário. De posse do hash, o invasor utiliza este ataque para testar combinações que possam gerar o hash procurado até que se chegue à resposta correta.
  36. Rainbow Table Exemplo Caso o usuário malicioso obtenha acesso aos hashs de senha (apenas visualizar), ele ainda assim terá de descobrir a senha que está ali. O problema está em confiar apenas na criptografia de hashs comuns como md5 e sha1 .
  37. Rainbow Table Exemplo Vamos pegar como exemplo a palavra abacaxi . O hash md5 referente é 4b96d5c1ff312eea069ddc760794963d . Supondo que obtemos este hash do banco de dados, basta digitá-lo no Google e em alguns segundos estamos prontos.
  38. Rainbow Table Exemplo
  39. Rainbow Table Como evitar A técnica mais utilizada e que reduz drasticamente a chance de este ataque dar certo, é “temperar” suas senhas. Ao inserir uma string arbitrária antes de criptografar a senha, este ataque torna-se praticamente inefetivo. À essa string arbitrária damos o nome de salt .
  40. Rainbow Table Como evitar Digamos que seu salt será rocknroll . Ao aplicar a criptografia na sua string, você deverá concatenar com o seu salt. md5("rocknroll" . $senha) Se a senha for abacaxi teremos o seguinte hash: 0a5cefae5c742e8a914f486db9ea45ef . E pra esse o Google não tem resposta! 😉 Leia mais sobre Rainbow Table: http://tinyurl.com/mais-sobre-rainbow-table
  41. Password Sniffing O que é? Este ataque baseia-se em capturar na rede um pacote descriptografado com os dados de autenticação de algum usuário. Como ocorre? Monitorando a rede pode-se visualizar todos os pacotes. Todas as requisições via POST e GET normalmente estão abertas à visualização.
  42. Password Sniffing Como evitar Proteja a sua conexão com SSL. Utilizando este protocolo você irá assegurar que a comunicação entre o cliente e o servidor, mesmo que interceptada, não possa ser decifrada. Utilize sempre o POST (por ser uma forma mais segura) e lembre-se de sempre colocar o protocolo HTTPS .
  43. Password Sniffing Como evitar Você pode também redirecionar o usuário para a página de login (o formulário em si) sempre com HTTPS. Não existe nenhuma razão técnica para isso, apenas psicológica. O usuário costuma sentir-se mais seguro quando está colocando sua senha em uma página com cadeado. 🙂 Leia mais sobre Sniffing: http://tinyurl.com/mais-sobre-sniffing
  44. Outros tipos de ameaça 3
  45. Outros tipos de ameaça
    • Includes
    • Abuso de formulários
    • Diretrizes (register_globlals, display_errors, etc)
    • Exposição do phpinfo

    Existem outras ameaças que vão além da alçada do programador. Outras podem ser evitadas se alguns cuidados forem tomados.

  46. Outros tipos de ameaça
    • A inclusão de arquivos via include() e require() , embora muito útil, pode ter consequencias muito ruins se não utilizada corretamente.
    • É muito comum a inclusão de arquivos recebidos via URL sem que a string seja filtrada.

    Includes

  47. Outros tipos de ameaça
    • Outro ponto que você deve estar atento é quanto ao uso de extensões que o seu servidor web não “conheça”.
    • Evite extensões do tipo .inc . Se for fazê-lo, prefira algo do tipo meuarquivo.inc.php .

    Includes

  48. Outros tipos de ameaça
    • Funções que você pode utilizar para filtrar os dados recebidos e evitar um ataque de XSS ou a exposição do seu código:
    • basename()
    • file_exists()

    Includes

  49. Outros tipos de ameaça
    • Esteja sempre atento ao uso de seus formulários.
    • O maior erro que você pode cometer é colocar os possíveis e-mails dentro do seu formulário.
    • Isto abrirá uma brecha em que o usuário mal intencionado poderá inserir endereços arbitrários e utilizar o seu formulário como disseminador de SPAM.

    Abuso de formulários

  50. Outros tipos de ameaça
    • Algumas diretrizes, quando bem configuradas, podem aumentar a segurança da sua aplicação.
    • register_globals
    • display_errors
    • log_errors

    Diretrizes

  51. Outros tipos de ameaça
    • É incrível o número de páginas espalhadas pela web que possuem um arquivo phpinfo.php em sua raiz.
    • A primeira ação tomada por um usuário mal intencionado é verificar a existência desse arquivo e de variantes do seu nome como info.php , php.php , etc.

    Exposição do phpinfo

  52. Mais alguns cuidados 4
  53. Mais alguns cuidados
    • Lei do menor privilégio (SQL)
    • Ocultação de cabeçalhos HTTP
    • Examine sempre os logs

    Existem mais alguns cuidados que você pode tomar para assegurar que será mais difícil conseguir realizar um ataque bem sucedido contra a sua aplicação.

  54. Mais alguns cuidados Lei do menor privilégio (SQL) Sempre que possível, crie mais de um usuário para acesso ao banco de dados. Não é uma boa idéia utilizar o usuário administrador (root) para acessar o banco através do site.
  55. Mais alguns cuidados Lei do menor privilégio (SQL) Crie usuários que só tenham permissão de leitura e usuários que só tenham permissão de escrita . Caso, devido a algum infortuno do destino, alguém consiga invadir o seu sistema terá apenas permissões limitadas.
  56. Mais alguns cuidados Ocultação de cabeçalhos HTTP Sempre que você acessa uma página, o servidor envia cabeçalhos HTTP para o seu browser. Dentro deste cabeçalhos podemos encontrar algumas informações interessantes.
  57. Mais alguns cuidados Ocultação de cabeçalhos HTTP
  58. Mais alguns cuidados Ocultação de cabeçalhos HTTP Dentro do arquivo httpd.conf do Apache você pode alterar o nível de exposição da versão das aplicações instaladas no seu servidor. Para tanto, você deve alterar a diretiva ServerTokens .
  59. Mais alguns cuidados Ocultação de cabeçalhos HTTP
    • ServerTokens valor_desejado
    • Prod: Apache
    • Major: Apache/2
    • Minor: Apache/2.0
    • Min: Apache/2.0.59
    • OS: Apache/2.0.59 (Unix)
    • Full: Apache/2.0.59 (Unix) PHP/5.2.6
  60. Mais alguns cuidados Examine sempre os logs Esteja atento aos logs e, se possível, utilize ferramentas de monitoramento de tráfego (como AWStats e Webalizer) para analisar possíveis tentativas de ataque à sua página.

 

 

Quer ler mais sobre PHP?

Ver mais posts sobre PHP

Verificar se uma string é vazia com javascript

Depois do post sobre performance no Javascript aqui vai um  fastpost , também falando de javascript. Hoje vou mostrar uma função simples que utiliza uma expressão regular para verificar se o valor passado é nulo ou não.

Não há muito o que explicar, então segue o código:

function notNull (x){
        if(a!="" && !(a.match(/^\s+$/))){
            return true;
        }else{
            return false;
}


Para verificar se alguma string é nula é só chamar a função notNull(string).

A primeira verificação do if é para ver se a string passada (x) não é vazia, depois a expressão regular  (/^\s+$/) se encarrega do resto, verificando se x não é composta apenas de espaços.

Utilizei esta função para validar um campo de busca, já que neste caso o usuário não poderia buscar apenas espaços ou dar submit na busca vazia.

A função retorna true quando a string é válida (não é vazia e não é composta apenas por espaços) e false quando o contrário ocorre.

Aqui vai um exemplo (utilizando jQuery) de como validar um form de busca, onde o input com id search é o campo de busca.

if(notNull($("#search").val()){

    $("#searchForm").submit;

else{

    alert("A busca está vazia.");

}
 

E para quem quer aprender funções regulares, já li e recomendo o livro Expressões Regulares: uma abordagem divertida.