Introdução ao CSRF
CSRF (falsificação de solicitação de sites cruzados), Nome chinês: falsificação de solicitação de sítio, também conhecida como: Ataque/Sessão de um clique, abreviação: CSRF/XSRF.
Para introduções específicas e métodos de ataque de SCRF, consulte a introdução da enciclopédia de Baidu e a análise de um grandalhão:
Enciclopédia CSRF Baidu discute brevemente os métodos de ataque CSRF
Etapas de configuração
1. Depende do pacote JAR
<properties> <spring.security.version>4.2.2.RELEASE</spring.security.version> </properties> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${spring.security.version}</version> </dependency> <dependency> <GroupId> org.springframework.security </groupiD> <TRAFACTID> Spring-Segurança-web </ArtifactId> <Versão> $ {spring.security.version} </version> </dependency> <pendency> <puperid> org.springframework.security </Grupoid> <versão> $ {spring.security.version} </versão> </dependency> 2.Web.xml Configuração
<filter> <filter-name> SpringSecurityFilterchain </ftrid-Name> <filter-Class> org.springframework.web.filter.delegatingFilterProxy </filter-class> </filtern--Mapping> <tril-name> spRenSecertionFilterChiAn </filtername> <urll-pnating> <rinfter-name> spRinStingfilterChilterChin <bilt-Name> <urll-PAPLE>
3. Configuração da configuração da mola Configuração
<bean id = "csrfSecurityRequestMatcher"> </bean> <Segurança: http auto-config = "true" use-expressions = "true"> <segurança: headers> <security: ardem-opções donabled = "true"/> </security> <security> <securion: csrf request-mcherefr = "true"/> </security> <segurança> <securion: csrf-med matcher-rref = "true"/> </security> <segurança> <segurança: csrf-matcher-rre = " </segurança: http>
4. Personalize a classe de implementação do requestmatcher csrfSecurityRequestMatcher
Esta classe é usada para personalizar quais solicitações não requerem interceptação e filtragem. Se o CSRF estiver configurado, todas as solicitações HTTP serão interceptadas pelo CSRffilter, e existe uma classe privada DefaultreCirescSrfMatcher no CSRffilter.
Código Fonte 1: Classe DefaultreCirescSrfMatcher
Classe final estática privada DefaultrecirescSrfMatcher implementa o requestMatcher {private final HashSet <String> AllowMethods; Private DefaultreCirescSrfMatcher () {this.allowedMethods = new HashSet (Arrays.asList (new String [] {"Get", "Head", "Trace", "Options"})); } Public Boolean Matches (httpServletRequest Request) {return this.allowedmethods.contains (request.getMethod ()); }} A partir desse código -fonte, podemos descobrir que o método de postagem é excluído, ou seja, apenas os quatro tipos de métodos como get | Head | Trace | Opções serão lançados. As solicitações HTTP de outros métodos devem verificar se o token _CSRF está correto. Geralmente, ao chamar o serviço de interface restante no método do post, não há token _csrf, o que fará com que nossa interface de repouso falhe. Precisamos personalizar uma classe para liberar a interface desse tipo. Vamos dar uma olhada em nossos filtros personalizados:
Código fonte 2: CSRFSecurityRequestMatcher Class
classe pública CSRFSecurityRequestMatcher implementa o requestmatcher {padrão privado permitidoMethods = Pattern.compile ("^(Get | Head | Trace | Opções) $"); private regexRequestMatcher UMNOTETECTMATCHER = new RegexRequestMatcher ("^/Rest /.*", null); @Override Public Boolean Matches (httpServletRequest Request) {if (alpedmethods.matcher (request.getMethod ()). Matches ()) {return false; } retornar! UMPROTECTMATCHER.MATCHES (request); }} Nota: Geralmente, os serviços de interface restantes que definimos são todos com /REST /, portanto, se o seu projeto não for usado ou não houver serviço REST no projeto, essa classe poderá ser completamente omitida.
5. Configuração da solicitação do post
Geralmente, existe um arquivo JSP comum em nosso projeto, que é referenciado por cada página, para que possamos fazer a seguinte configuração no arquivo comum:
<meta name = "_ csrf" content = "$ {_ csrf.token}"/> <meta name = "_ csrf_header" content = "$ {_ csrf.headername}"/> <cript> var token = $ ("meta [name = '_ csrf'] var cabeçalho = $ ("meta [nome = '_ csrf_header']"). att ("content"); $ .ajaxSetup ({beforesend: function (xhr) {if (cabeçalho && token) {xhr.setRequestHeader (cabeçalho, token);}}}); </script> $ .ajaxsetup significa adicionar este cabeçalho e token a todas as nossas solicitações, ou coloque -o no formulário. Observe que _csrf deve corresponder à configuração no arquivo de configuração da segurança da mola e o padrão é _CSRF.
Análise do código -fonte
Sabemos que, como o CSRF está configurado, todas as solicitações HTTP serão interceptadas pelo CSRffilter; portanto, depois de olhar para o código -fonte do CSRFFILTER, você ficará claro sobre o princípio rapidamente. Aqui, apenas olhamos para o método de filtragem específico:
Código -fonte 3: Método Dofilterinternal de CSRffilter
Void protegido DofilterInternal (solicitação HttpServletRequest, resposta HttpServletResponse, filtragem filtragem) lança servletexception, ioexception {request.setAttribute (httpServletResponse.class.getName (), resposta); CSRFTOKEN CSRFTOKEN = this.tokenrepository.loadToken (solicitação); boolean MissingToken = csrftoken == null; if (MissingToken) {// Se o token estiver vazio, significa que a primeira vez que você o acessar, gera um objeto de token CSRFTOKEN = this.tokenRepository.generateToken (request); this.TokenRepository.SaveToken (csrftoken, solicitação, resposta); } request.setAttribute (csrftoken.class.getName (), csrftoken); // Coloque o objeto de token na solicitação, observe que a chave aqui é csrftoken.getParameterName () = _csrf, por isso a escrevemos para a morte na página. request.setAttribute (csrftoken.getParameterName (), csrftoken); // Esta máquina é o filtro que personalizamos no arquivo de configuração da mola, ou seja, obtenha, cabeça, rastreamento, opções e nosso descanso não lide if (! This.RequirecsrfProtectionMatcher.matches (request)) {filterChain.dofilter (request, resposta); } else {string realToken = request.getheader (csrftoken.getheaderName ()); if (realToken == NULL) {realToken = request.getParameter (csrftoken.getParameterName ()); } if (! csrftoken.getToken (). Equals (realToken)) {if (this.logger.isdebugenabled ()) {this.logger.debug ("Token inválido de CSRF encontrado para" + urlutils.buildfullRequesturl (request); } if (MissingToken) {this.accessdeniedHandler.Handle (solicitação, resposta, novo MissingCSrftOkeNexception (realToken)); } else {this.accessdeniedHandler.handle (solicitação, resposta, novo invalidcsrftocenexception (csrftoken, realToken)); }} else {filterChain.dofilter (solicitação, resposta); }}}Como pode ser visto no código -fonte, outras solicitações de postagem além de nossos filtros personalizados precisam de verificação de token.
Originalmente, eu queria tirar uma captura de tela para obter um caso e depois usar o ponto de interrupção para ver o status de transmissão de valor da página e o plano de fundo ... no entanto, não posso fazer upload de fotos aqui e enlouquecer. Ok, muito para resumir! Se você tiver alguma escrita errada ou outras perguntas, pode deixar uma mensagem para se comunicar.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.