Sumário Construção de sistema Administrativo... 1 Sistema de Login... 2 SQL INJECTION... 2 Técnicas para Evitar Ataques... 2 Formulário de Login e Senha fará parte do DEFAULT... 5 LOGAR... 5 boas... 6 TEMPLATE... 6 Criar Menu menu_adm... 8 Construção de sistema Administrativo Um sistema administrativo é composto por CRUDs e Sistema de Segurança através de Login e Senha. Nesse modelo, iremos ensinar como criar um sistema administrativo simples em PHP. Esse modelo é composto de duas partes LOGIN e CRUD. Nessa primeira parte iremos fazer somente o LOGIN. 1
Vamos iniciar a parte do LOGIN. Sistema de Login Iremos construir um sistema de login e senha para garantir a segurança do sistema administrativo. SQL INJECTION Primeiro vamos falar de SQL INJECTION ou INJEÇÃO DE SQL Muitos desenvolvedores web não sabem de como consultas SQL podem ser manipuladas e presumem que uma consulta de SQL é um comando confiável. Significa que consultas SQL são capazes de passar imperceptível por controles de acesso, portanto desviando da autenticação padrão e de checagens de autorização, e algumas vezes consultas SQL podem permitir acesso à comando em nível do sistema operacional do servidor. Injeção direta de comandos SQL é uma técnica onde um atacante cria ou altera comandos SQL existentes para expor dados escondidos, ou sobrescrever dados valiosos, ou ainda executar comandos de sistema perigosos no servidor. Isso é possível se a aplicação pegar a entrada do usuário e combinar com parâmetros estáticos para montar uma consulta SQL. Os exemplos a seguir são baseados em histórias verdadeiras, infelizmente. Devido à falta de validação de entrada e conectando ao banco de dados usando o super-usuário ou um usuário que pode criar usuário, o atacante pode criar um super-usuário no seu banco de dados. Técnicas para Evitar Ataques Você pode dizer que o atacante precisa possuir um pouco de informação sobre o esquema de banco de dados na maioria dos exemplos. Você tem razão, mas você nunca sabe quando e como isso pode ser obtido e, se acontecer, seu banco de dados pode ficar exposto. Se você estiver usando um pacote open source publicamente disponível para lidar com banco de dados, que pode pertencer a um sistema de controle de conteúdo ou fórum, os invasores facilmente produzem uma cópia de parte de seu código. Também pode ser um risco de segurança se este for mal desenhado. Esses ataques se baseiam principalmente em explorar falhas no código escrito sem se preocupar com segurança. Nunca confie em nenhum tipo de entrada, especialmente aquela que vem do lado do cliente, mesmo que venha de um combobox, um campo de entrada escondido (hidden) ou um cookie. O primeiro exemplo mostra como uma consulta inocente pode causar desastres. Nunca conecte ao banco de dados como um super-usuário ou como o dono do banco de dados. Use sempre usuários personalizados com privilégios bem limitados. Verifique se uma entrada qualquer tem o tipo de dados esperado. O JSP tem um grande número de funções de validação de entrada, desde as mais simples encontrada em Funções de Variáveis e em Funções de Tipo de Caracteres (ex.: Integer.parseInt Float.parseFloat() além de usar o suporte a Expressões Regulares Compatível com Perl. Se a aplicação espera por entradas numéricas, considere verificar os dados com a função Integer.parseInt para transformar a string em número se não for com try cash você trata o erro. 1. int num = 0; 2. String recebido = "123"; // o que foi recebido 2
3. try{ 4. num = Integer.parseInt(recebido); 5. 6. }catch(exception ex){ 7. //se der erro mantém o numero como 0 8. num = 0; 9. //System.out.println("Erro = " + ex); 10. } Dai se o numero for 0 você trata a mensagem de erro. AULA APLICAÇÕES PARA WEB Tente testar se um site entra SQL injection preenchendo apenas o campo de login com " OR "=' e na senha deixe vazio, clique no botão e você conseguirá acessar a área administrativa e fuçar tudo. Me pergunte como? Dizendo que você preencheu no login esse código, veja como ficaria na query. $query ="SELECT id FROM users WHERE username = '' OR =' AND password = ''"; O OR faz com que seja ignorado a parte da senha e o acesso é feito sem nada. Agora vamos construir nosso sistema de login e senha. Abra seu projeto de site noticias e vamos criar uma pasta chamada admin e dentro dela um index.jsp com o seguinte código. 3
Agora vamos criar a seguinte rotina de script. Com o IF vamos controlar com a varivel do tipo get cod toda a funcionalidade dessa pagina. String content; content = ""; if(request.getparameter("cod")!= null){ }else{ 4
} A variável string contente em cada trecho fará uma parte do código no default terá um formulário de login e senha como segue abaixo. Formulário de Login e Senha fará parte do DEFAULT content ="<fieldset>"; content +="<legend>login</legend>\n"; content +="<form action=\"/admin/index.jsp?cod=logar\" method=\"post\">\n"; content +="<label>login</label>\n"; content +="<input type=\"text\" class=\"campos\" name=\"login\" size=\"12\"><br />\n"; content +="<label>senha</label>\n"; content +="<input type=\"password\" class=\"campos\" name=\"senha\" size=\"12\">\n"; content +="<div align=\"right\"><input type=\"submit\" class=\"botoes\" value=\"ok\"></div>\n"; content +="</form>\n"; content +="</fieldset>\n"; Esse script cria podendo ser possível passar alguma mensagem de erro. LOGAR Veja o script da PARTE DO LOGIN String login = request.getparameter("login"); String senha = request.getparameter("senha"); String erro = "";//mensagem de erro zerada rs = statement.executequery("select * FROM usuarios WHERE usuario_login ='"+login+"' AND usuario_senha ='"+senha+"'"); rs.next(); int qtd = rs.getint(1); if(qtd > 0 ) {// se existir session.setattribute( "user", rs.getstring("usuario_login")); session.setattribute( "id", rs.getstring("usuario_id")); session.setattribute( "nome_user", rs.getstring("usuario_nome")); String site = new String("boas.jsp"); response.setstatus(response.sc_moved_temporarily); response.setheader("location", site); }else { usuario erro= "Usuário ou senha inválida!";//mensagem de erro de } 5
content = erro; // instancio o formulario de login com as mensagens de erro, se houverem O script acima utilizo a variável GET cod para delimitar a ação da pagina, quando está em default, ou seja, sem ser informada, ela carrega o formulário de login. No caso de LOGAR, ela recupera as variáveis de login e senha digitadas no formulário, trata o SQL INJECTION e faz o login, conforme explicação no código. boas TEMPLATE Seja bemvindo, <%= session.getattribute( "nome_user" ) %> Seja bemvindo, <%= session.getattribute( "nome_user" ) %> Crie um template chamado admin que no meio dele sempre irá carregar conteúdo do admin. Lembre-se que o menu do admin é diferente, como ele será uma arquivo único, vamos criar apenas um template que irá carregar tudo no meio sempre na variável content. Depois devemos incluir o script dos templates das páginas, veja o passo a passo abaixo. 6
7
Criar Menu menu_adm Vá em inc e crie um arquivo menu_adm com o código abaixo. <% String menu; menu = ""; if(session.getattribute( "nome_user" )!= null) { menu = "<ul> <li><a hr ef=\"crudnoticia.jsp\">notícia</a></li> 8
<li><a href=\"logout.jsp\">sair</a></li> </ul>"; }else{ menu = "Área reservada!"; } out.println(menu); %> 9