Nos últimos tempos, um problema recorrente e perigoso em aplicações web conhecido como CSRF (Cross-Site Request Forgery)
tem sido muito comentado. Um ataque de CSRF consiste em inserir
requisições em uma sessão já aberta pelo usuário. O processo básico é:
Para evitar ataques de CSRF, a aplicação pode implementar as recomendações do item Usar corretamente POST e GET e também utilizar valores aleatórios a serem incluídos em cada formulário como um campo escondido, como mostra o exemplo abaixo: <form ...> <input type="hidden" name="csrf_value" value="8dcb5e56904d9b7d4bbf333afdd154ca"> O valor aleatório incluído no campo csrf_value deve ser armazenado pela aplicação na sessão do usuário para que a aplicação verifique se a próxima requisição contém o valor correto. Assim, toda vez que a aplicação receber uma requisição via POST, deve-se verificar se o valor aleatório está presente e se corresponde ao valor esperado. Outra alternativa é incluir o valor aleatório em um cookie, o que evita a necessidade de manter informações na sessão do usuário. No entanto, a menos que o browser implemente a same-origin policy, um script poderia capturar o valor aleatório no formulário em enviá-lo na requisição. Ou seja, uma proteção completa contra CSRF depende também do browser do usuário. A grande maioria dos browsers atuais implementa esta política, o que nos permite acreditar que a solução delineada acima apresenta proteção adequada contra CSRF. O projeto CSRFGuard do OWASP é um filtro J2EE que insere os identificadores aleatórios nas páginas HTML e verifica estes identificadores automaticamente, já que após inserir na página, o identificador é também armazenado na sessão do usuário. No Struts, é possível utilizar tokens aleatórios para implementar esta funcionalidade. Estes tokens foram projetados para evitar que uma requisição seja submetida mais de uma vez, mas, como implementam a funcionalidade descrita acima, podem ser usados para evitar CSRF. Os funções que o Struts implementa para a manipulação destes tokens são:
Classe Action que gera um novo token antes de chamar a página JSP: public class LoadAction extends Action { public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) { ActionForward forward; forward=mapping.findForward("FirstPage");// página JSP onde será usado o token saveToken(request); return forward; } } O token deve então ser colocado num campo tipo hidden na página. O JSP abaixo mostra como fazer: <%@ page import="org.apache.struts.action.Action"%> <%@ page import="org.apache.struts.taglib.html.Constants"%> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html> <head> <title> First Page </title> </head> <body> <form name="MyForm" method="post" action="/dpsubm/getForm/submit.do"> <input type="text" name="name" > <input type="hidden" name="<%= Constants.TOKEN_KEY %>" value="<%= session.getAttribute(Action.TRANSACTION_TOKEN_KEY) %>" > <input type="submit" value="submit"> </form> </body> </html> A classe Action que recebe os dados do formulário deve verificar a validade do token antes de executar a sua lógica. O token deve ser invalidado para não ser reusado. public class SubmitAction extends Action { public ActionForward execute(ActionMapping mapping ,ActionForm form ,HttpServletRequest request,HttpServletResponse response) { ActionForward forward=mapping.findForward("submitForm"); DupSubmitForm frm=(DupSubmitForm)form; if(isTokenValid(request)) { System.out.println("frm.getName()"+frm.getName()); resetToken(request); } else { System.out.println("frm.getName()"+frm.getName()); System.out.println("Formulário já foi submetido. Recarregue a página e tente novamente."); } return forward; } } O Struts não implementa o controle dos tokens via cookies, apenas via campos tipo hidden. Para outras técnicas que ajudam a evitar CSRF, veja os itens Usar corretamente POST e GET e Re-autenticar antes de operações críticas. FonteZELLER, William and FELTEN, Edward W. Cross-site Request Forgery: Exploitation and Prevention. Sptember 2008: http://www.freedom-to-tinker.com/sites/default/files/csrf.pdfJava Developers Forum: http://x86.sun.com/thread.jspa?messageID=10340370 |
Início >