Introducción a CSRF
CSRF (falsificación de solicitud de sitio cruzado), Nombre chino: falsificación de solicitudes de sitios cruzados, también conocido como: Ataque de un clic/Riding, Abreviatura: CSRF/XSRF.
Para introducciones específicas y métodos de ataque de SCRF, consulte la introducción de la enciclopedia de Baidu y el análisis de un gran tipo:
CSRF Baidu Enciclopedia analiza brevemente los métodos de ataque CSRF
Pasos de configuración
1. Depende del paquete jar
<Properies> <Spring.Security.Version> 4.2.2.Release </spring.security.version> </propiies> <pendency> <MoupRupid> org.springframework.security </groupId> <artifactid> spring-security-core <//veleCiD> <PROPESIONADO $ {spring.security.version} </versión> spring-security-core <///vele> <presion> $ {spring.security.version} </versión> spring-security-core <////1/version> </version> </versión> </versión> </versión> </artificial> <tendency> <MoupRoD> org.springframework.security </groupid> <artifactid> spring-security-web </artifactid> <lection> $ {spring.security.version} </versión> </pendency> <ependency> <uproupid> org.springframework.eseCurity </proupid> <artifactId> Spring-Security-Config </artifactId> <versión> $ {Spring.Security.Version} </ververse> </dependencia> 2. Configuración de Web.xml
<Scilt> <Sterry-Name> SpringSecurityFilterChain </filter-Name> <Slast-Class> org.springframework.web.filter.DelegatingFilterProxy </filter-class> </filter> <filter-mapping> <filter-name> springsecurityfilterchain </filtre-name> <url-pattern>/*</url-patter
3. Configuración del archivo de configuración de resorte
<bean id = "csrfsecurityRequestMatcher"> </reme> <seguridad: http automático-config = "true" use-expressions = "true"> <Security: Headers> <Security: frame-options Discabled = "True"/> </Security: Headers> <SEGURIDAD: CSRF Solicit-Matcher-ref = "CSRFSECURITY </Security: http>
4. Personalice la clase de implementación de requestmatcher csrfsecurityRequestMatcher
Esta clase se utiliza para personalizar qué solicitudes no requieren intercepción y filtrado. Si CSRF está configurado, todas las solicitudes HTTP son interceptadas por CSRFFILTER, y hay una clase privada DeFaUtRequiresCSrfMatcher en CSRFFILTER.
Código de origen 1: clase de DeFaultuReCsrfMatcher
Clase final estática privada DeFaulTuquiresCSrfMatcher implementa requestmatcher {Hashset final privado <String> permitidomethods; privado deuTequirescSrfMatcher () {this. allowedmethods = new Hashset (arrays.aslist (new String [] {"get", "head", "traza", "opciones"})); } Public Boolean Matches (httpservletRequest solicitud) {return! this. allowedmethods.contains (request.getMethod ()); }} De este código fuente, podemos encontrar que el método de publicación está excluido, es decir, solo se lanzarán los cuatro tipos de métodos como Get | Head | Trace | Opciones. Las solicitudes HTTP de otros métodos deben verificar si el token _CSRF es correcto. Por lo general, al llamar al servicio de interfaz REST en el método de publicación, no hay token _csrf, lo que hará que nuestra interfaz de descanso falle. Necesitamos personalizar una clase para liberar la interfaz de este tipo. Echemos un vistazo a nuestros filtros personalizados:
Código fuente 2: CSRFSecurityRequestMatcher Clase
clase pública csrfsecurityRequestMatcher implementa requestmatcher {patrón privado permitidomethods = patrón.compile ("^(get | head | traza | opciones) $"); privado regexRequestMatcher improtectedMatcher = new RegexRequestMatcher ("^/REST /.*", nulo); @Override public Boolean Matches (httpservletRequest solicitud) {if (permitidoMethods.matcher (request.getMethod ()). Matches ()) {return false; } return! sin protección muncher.matches (solicitud); }} Nota: En general, los servicios de interfaz REST que definimos están todos con /REST /, por lo que si su proyecto no se usa o no hay servicio de descanso en el proyecto, esta clase puede omitirse por completo.
5. Configuración de solicitud de poste
En general, hay un archivo JSP común en nuestro proyecto, al que hace referencia a cada página, por lo que podemos hacer la siguiente configuración en el archivo común:
<meta name = "_ csrf" content = "$ {_ csrf.token}"/> <meta name = "_ csrf_header" content = "$ {_ csrf.headername}"/> <script> var token = $ ("meta [name = '_ csrf']"). Attr ("content");; Encabezado var = $ ("meta [name = '_ csrf_header']"). attr ("contenido"); $ .AJAXSETUP ({befefefefefefefore (xhr) {if (header && token) {xhr.setRequestheader (encabezado, token);}}}); </script> $ .AJAXSetUp significa agregar este encabezado y token a todas nuestras solicitudes, o ponerlo en el formulario. Tenga en cuenta que _CSRF debería coincidir con la configuración en el archivo de configuración de Spring Security, y el valor predeterminado es _CSRF.
Análisis del código fuente
Sabemos que dado que CSRF está configurado, todas las solicitudes HTTP serán interceptadas por CSRFFILTER, por lo que después de observar el código fuente de CSRFFILTER, estará claro sobre el principio de un vistazo. Aquí solo miramos el método de filtrado específico:
Código fuente 3: Método Dofilterinternal de CSRFFILTER
DOFILTERINTAL DE DOFILTERINTAL PROTEGido (httpservletRequest, respuesta httpservletResponse, filterchain filtreChain) arroja servletException, ioexception {request.setTribute (httpServletResponse.class.getName (), respuesta); Csrftoken csrftoken = this.TokenRepository.LoadToken (solicitud); Boolean MissingToken = CSRFTOKen == NULL; if (fallingToken) {// Si el token está vacío, significa que la primera vez que accede a él, genere un objeto token csrftoken = this.TokenRepository.GenerateToken (solicitud); this.TokenRepository.Savetoken (csrftoken, solicitud, respuesta); } request.setAttribute (csrftokoken.class.getName (), csrftoken); // Ponga el objeto token en la solicitud, tenga en cuenta que la clave aquí es csrftoken.getParamEtername () = _csrf, por lo que la escribimos a muerte en la página. request.setAttribute (csrftokoken.getParamTername (), csrftoken); // Esta máquina es el filtro que personalizamos en el archivo de configuración de Spring, es decir, get, head, traza, opciones y nuestro descanso no manejan si (! This.requirecsrfprotectionMatcher.matches (request)) {filterChain.DoFilter (solicitud, respuesta); } else {string realToken = request.getheader (csrftoken.getheadername ()); if (realToken == null) {realToken = request.getParameter (csrftokoken.getParametername ()); } if (! csrftokoken.gettokoken (). Equals (realToken)) {if (this.logger.isdeBugeNabled ()) {this.logger.debug ("token csrf inválido encontrado para" + urluTils.buildfulLRequesturl (request)); } if (fallecToken) {this.accessdeniedhandler.handle (solicitud, respuesta, nueva faltantecsrftokenexception (realToken)); } else {this.accessdeniedhandler.handle (solicitud, respuesta, nuevo invalidcsrftokenexception (csrftoken, realToken)); }} else {FilterChain.DoFilter (solicitud, respuesta); }}}Como se puede ver en el código fuente, las solicitudes de publicación distintas de nuestros filtros personalizados requieren verificación de token.
Originalmente, quería tomar una captura de pantalla para obtener un caso, y luego usar el punto de interrupción para ver el estado de la transmisión de valor de la página y el fondo ... Sin embargo, no puedo subir imágenes aquí y volverlo loco. Ok, ¡mucho para resumir! Si tiene alguna escritura incorrecta o tiene otras preguntas, puede dejar un mensaje para comunicarse.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.