Table des matières
Principe CSRF
Pratique CSRF
Défense CSRF
Solution de non-séparation backend et backend
前后端分离方案
Maison Java javaDidacticiel Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

May 12, 2023 pm 09:13 PM
springboot csrf

Principe CSRF

Si nous voulons nous défendre contre les attaques CSRF, nous devons d'abord comprendre ce qu'est une attaque CSRF. Voyons le processus d'attaque CSRF à travers l'illustration suivante :

Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

En fait, ce processus est très. simple :
1. Supposons que l'utilisateur ouvre le site Web China Merchants Online Banking et se connecte.
2. Après une connexion réussie, les services bancaires en ligne renverront le cookie au front-end et le navigateur enregistrera le cookie.
3. L'utilisateur a ouvert un nouvel onglet dans le navigateur sans se déconnecter des services bancaires en ligne, puis a visité un site Web dangereux.
4. Il y a un hyperlien sur ce site Web dangereux, et l'adresse de l'hyperlien pointe vers China Merchants Online Banking.
4. L'utilisateur clique sur ce lien. Étant donné que cet hyperlien portera automatiquement le cookie enregistré dans le navigateur, l'utilisateur accède sans le savoir aux services bancaires en ligne, ce qui peut lui causer des pertes.

Le processus du CSRF est à peu près comme ceci. Ensuite, j'utiliserai un exemple simple pour montrer ce qu'est le CSRF.

Pratique CSRF

1. J'ai créé un projet Spring Boot nommé csrf-mry. Ce projet est équivalent au site de banque en ligne que nous avons mentionné ci-dessus, j'ai introduit les dépendances Web et Spring Security, comme suit :

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>
Copier après la connexion
.

2 .Une fois la création réussie, pour plus de commodité, nous configurons directement le nom d'utilisateur/mot de passe Spring Security dans le fichier application.properties :

server.port= 8866
spring.security.user.name=javaboy
spring.security.user.password=123
Copier après la connexion

3 Ensuite, nous fournissons deux interfaces de test

package com.mry.csrf.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CsrfDemoController {
    @PostMapping("/transfer")
    public void transferMoney(String name, Integer money) {
        System.out.println("name = " + name);
        System.out.println("money = " + money);
    }
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}
Copier après la connexion

en supposant que /transfer est une interface de transfert ( En supposant qu'il s'agisse principalement de démontrer les attaques CSRF à tout le monde, la véritable interface de transfert est plus compliquée que cela).

4. Nous devons également configurer Spring Security, car Spring Security peut automatiquement se défendre contre les attaques CSRF par défaut, nous devons donc désactiver cette option.

package com.mry.csrf.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .csrf()
                .disable();
    }
}
Copier après la connexion

Une fois la configuration terminée, nous démarrons le projet csrf-simulate-web.

5. Créons un autre projet csrf-loophole-web. Ce projet est équivalent à un site Web dangereux, pour plus de commodité, il suffit d'introduire les dépendances Web lors de sa création ici.
Une fois le projet créé avec succès, modifiez d'abord le port du projet :

server.port= 8855
Copier après la connexion

6. Ensuite, nous créons un hello.html dans le répertoire resources/static avec le contenu suivant.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8866/transfer" method="post">
        <input type="hidden" value="javaboy" name="name">
        <input type="hidden" value="10000" name="money">
        <input type="submit" value="点击查看美女图片">
    </form>
</body>
</html>
Copier après la connexion

Il y a un lien hypertexte ici. Le texte du lien hypertexte est cliquez pour voir la photo d'une belle femme. Lorsque vous cliquez sur le lien hypertexte, il demandera automatiquement l'interface http://localhost:8866/transfer. temps, le domaine caché comporte également deux paramètres.

Une fois la configuration terminée, vous pouvez démarrer le projet csrf-loophole-web.

Ensuite, l'utilisateur accède d'abord à l'interface du projet csrf-simulate-web. Lors de l'accès, il doit se connecter et l'utilisateur effectue l'opération de connexion une fois l'accès terminé, l'utilisateur n'effectue pas l'opération de déconnexion. , puis l'utilisateur accède à csrf-loophole. -Sur la page Web, j'ai vu le lien hypertexte et j'étais curieux de savoir à quoi ressemblait cette beauté. Dès que j'ai cliqué dessus, l'argent a été transféré.

Défense CSRF

Parlons d'abord des idées de défense.

Défense CSRF, une idée centrale est d'ajouter un nombre aléatoire à la requête frontale.

Parce que lors d'une attaque CSRF, le site Web du pirate informatique ne sait pas réellement ce qu'est le cookie de l'utilisateur. Il permet à l'utilisateur d'envoyer lui-même une demande au site Web de banque en ligne, car ce processus transportera automatiquement les informations dans le cookie.

Notre idée de défense est donc la suivante : lorsque l'utilisateur accède à la banque en ligne, en plus de transporter les informations contenues dans le cookie, il doit également porter un numéro aléatoire. Si l'utilisateur ne porte pas ce numéro aléatoire, le site de banque en ligne le fera. rejeter la demande. Lorsqu'un site Web pirate incite les utilisateurs à cliquer sur un lien hypertexte, il contiendra automatiquement les informations dans le cookie, mais il ne contiendra pas automatiquement le nombre aléatoire, évitant ainsi avec succès les attaques CSRF.

Spring Security fournit un bon support pour cela, jetons un coup d'œil.

Solution de non-séparation backend et backend

Spring Security fournit en fait une défense CSRF par défaut, mais cela oblige les développeurs à faire plus de choses.
Nous créons d’abord un nouveau projet Spring Boot et introduisons Spring Security, Thymeleaf et les dépendances Web lors de sa création.

1.pom information

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>
Copier après la connexion

2. Une fois le projet créé avec succès, nous configurons toujours le nom d'utilisateur/mot de passe dans application.properties

spring.security.user.name=mry
spring.security.user.password=123456
Copier après la connexion

3 Ensuite, nous fournissons une interface de test

package com.mry.csrf.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SecurityCsrfController {
    @PostMapping("/hello")
    @ResponseBody
    public String hello() {
        return "hello";
    }
}
Copier après la connexion

Notez que cette interface de test est. Une requête POST, car par défaut, GET, HEAD, TRACE et OPTIONS ne nécessitent pas de vérification pour les attaques CSRF.

4. Ensuite, nous créons un nouveau modèle thymeleaf dans le répertoire resources/templates

<!DOCTYPE html>
<!--导入thymeleaf的名称空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/hello" method="post">
        <input type="hidden" th:value="${_csrf.token}" th:name="${_csrf.parameterName}">
        <input type="submit" value="hello">
    </form>
</body>
</html>
Copier après la connexion

Notez que lors de l'envoi de la requête POST, un champ caché supplémentaire est transporté. La clé du champ caché est ${_csrf.parameterName}. la valeur est ${_csrf.token}.

Le serveur apportera automatiquement ces deux valeurs, il suffit de les restituer sur le front-end.

5. Ajoutez ensuite un contrôleur à la page hello.html frontale

@GetMapping("/hello")
public String hello2() {
	return "hello";
}
Copier après la connexion

6. Une fois l'ajout terminé, démarrez le projet et nous accédons à la page hello. Lors de l'accès, vous devez d'abord vous connecter. la connexion est réussie, nous pouvons voir la connexion. Il y a aussi un paramètre supplémentaire dans la requête

Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

这里我们用了 Spring Security 的默认登录页面,如果大家使用自定义登录页面,可以参考上面 hello.html 的写法,通过一个隐藏域传递 _csrf 参数。

访问到 hello 页面之后,再去点击【hello】按钮,就可以访问到 hello 接口了。

Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

这是 Spring Security 中默认的方案,通过 Model 将相关的数据带到前端来。

如果你的项目是前后端不分项目,这种方案就可以了,如果你的项目是前后端分离项目,这种方案很明显不够用。

前后端分离方案

如果是前后端分离项目,Spring Security 也提供了解决方案。
这次不是将 _csrf 放在 Model 中返回前端了,而是放在 Cookie 中返回前端,配置方式如下:

package com.mry.csrf.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}
Copier après la connexion

有小伙伴可能会说放在 Cookie 中不是又被黑客网站盗用了吗?其实不会的,大家注意如下两个问题:
(1)黑客网站根本不知道你的 Cookie 里边存的啥,他也不需要知道,因为 CSRF 攻击是浏览器自动携带上 Cookie 中的数据的。
(2)我们将服务端生成的随机数放在 Cookie 中,前端需要从 Cookie 中自己提取出来 _csrf 参数,然后拼接成参数传递给后端,单纯的将 Cookie 中的数据传到服务端是没用的。
理解透了上面两点,你就会发现 _csrf 放在 Cookie 中是没有问题的,但是大家注意,配置的时候我们通过 withHttpOnlyFalse 方法获取了 CookieCsrfTokenRepository 的实例,该方法会设置 Cookie 中的 HttpOnly 属性为 false,也就是允许前端通过 js 操作 Cookie(否则你就没有办法获取到 _csrf)。

配置完成后,重启项目,此时我们就发现返回的 Cookie 中多了一项:

Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

接下来,我们通过自定义登录页面,来看看前端要如何操作。

首先我们在 resources/static 目录下新建一个 html 页面叫做 login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
</head>
<body>
<div>
    <input type="text" id="username">
    <input type="password" id="password">
    <input type="button" value="登录" id="loginBtn">
</div>
<script>
    $("#loginBtn").click(function () {
        let _csrf = $.cookie(&#39;XSRF-TOKEN&#39;);
        $.post(&#39;/login.html&#39;,{username:$("#username").val(),password:$("#password").val(),_csrf:_csrf},function (data) {
            alert(data);
        })
    })
</script>
</body>
</html>
Copier après la connexion

这段 html 给大家解释一下:
(1)首先引入 jquery 和 jquery.cookie ,方便我们一会操作 Cookie。
(2)定义三个 input,前两个是用户名和密码,第三个是登录按钮。
(3)点击登录按钮之后,我们先从 Cookie 中提取出 XSRF-TOKEN,这也就是我们要上传的 csrf 参数。
(4)通过一个 POST 请求执行登录操作,注意携带上 _csrf 参数。

服务端我们也稍作修改,如下:

package com.mry.csrf.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/static/js/**");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html")
                .successHandler((req,resp,authentication)->{
                    resp.getWriter().write("success");
                })
                .permitAll()
                .and()
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}
Copier après la connexion

一方面这里给 js 文件放行。

另一方面配置一下登录页面,以及登录成功的回调,这里简单期间,登录成功的回调我就给一个字符串就可以了。在登录成功后回调的详细解释。

OK,所有事情做完之后,我们访问 login.html 页面,输入用户名密码进行登录,结果如下:

Quel est le processus et le principe de défense de SpringBoot contre les attaques CSRF ?

可以看到,我们的 _csrf 配置已经生效了。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment Springboot intègre Jasypt pour implémenter le chiffrement des fichiers de configuration Comment Springboot intègre Jasypt pour implémenter le chiffrement des fichiers de configuration Jun 01, 2023 am 08:55 AM

Introduction à Jasypt Jasypt est une bibliothèque Java qui permet à un développeur d'ajouter des fonctionnalités de chiffrement de base à son projet avec un minimum d'effort et ne nécessite pas une compréhension approfondie du fonctionnement du chiffrement. Haute sécurité pour le chiffrement unidirectionnel et bidirectionnel. technologie de cryptage basée sur des normes. Cryptez les mots de passe, le texte, les chiffres, les binaires... Convient pour l'intégration dans des applications basées sur Spring, API ouverte, pour une utilisation avec n'importe quel fournisseur JCE... Ajoutez la dépendance suivante : com.github.ulisesbocchiojasypt-spring-boot-starter2 1.1. Les avantages de Jasypt protègent la sécurité de notre système. Même en cas de fuite du code, la source de données peut être garantie.

Comment utiliser Redis pour implémenter des verrous distribués dans SpringBoot Comment utiliser Redis pour implémenter des verrous distribués dans SpringBoot Jun 03, 2023 am 08:16 AM

1. Redis implémente le principe du verrouillage distribué et pourquoi les verrous distribués sont nécessaires. Avant de parler de verrous distribués, il est nécessaire d'expliquer pourquoi les verrous distribués sont nécessaires. Le contraire des verrous distribués est le verrouillage autonome. Lorsque nous écrivons des programmes multithreads, nous évitons les problèmes de données causés par l'utilisation d'une variable partagée en même temps. Nous utilisons généralement un verrou pour exclure mutuellement les variables partagées afin de garantir l'exactitude de celles-ci. les variables partagées. Son champ d’utilisation est dans le même processus. S’il existe plusieurs processus qui doivent exploiter une ressource partagée en même temps, comment peuvent-ils s’exclure mutuellement ? Les applications métier d'aujourd'hui sont généralement une architecture de microservices, ce qui signifie également qu'une application déploiera plusieurs processus si plusieurs processus doivent modifier la même ligne d'enregistrements dans MySQL, afin d'éviter les données sales causées par des opérations dans le désordre, les besoins de distribution. à introduire à ce moment-là. Le style est verrouillé. Vous voulez marquer des points

Comment résoudre le problème selon lequel Springboot ne peut pas accéder au fichier après l'avoir lu dans un package jar Comment résoudre le problème selon lequel Springboot ne peut pas accéder au fichier après l'avoir lu dans un package jar Jun 03, 2023 pm 04:38 PM

Springboot lit le fichier, mais ne peut pas accéder au dernier développement après l'avoir empaqueté dans un package jar. Il existe une situation dans laquelle Springboot ne peut pas lire le fichier après l'avoir empaqueté dans un package jar. La raison en est qu'après l'empaquetage, le chemin virtuel du fichier. n’est pas valide et n’est accessible que via le flux Read. Le fichier se trouve sous les ressources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

Comment implémenter Springboot+Mybatis-plus sans utiliser d'instructions SQL pour ajouter plusieurs tables Comment implémenter Springboot+Mybatis-plus sans utiliser d'instructions SQL pour ajouter plusieurs tables Jun 02, 2023 am 11:07 AM

Lorsque Springboot+Mybatis-plus n'utilise pas d'instructions SQL pour effectuer des opérations d'ajout de plusieurs tables, les problèmes que j'ai rencontrés sont décomposés en simulant la réflexion dans l'environnement de test : Créez un objet BrandDTO avec des paramètres pour simuler le passage des paramètres en arrière-plan. qu'il est extrêmement difficile d'effectuer des opérations multi-tables dans Mybatis-plus. Si vous n'utilisez pas d'outils tels que Mybatis-plus-join, vous pouvez uniquement configurer le fichier Mapper.xml correspondant et configurer le ResultMap malodorant et long, puis. écrivez l'instruction SQL correspondante Bien que cette méthode semble lourde, elle est très flexible et nous permet de

Comparaison et analyse des différences entre SpringBoot et SpringMVC Comparaison et analyse des différences entre SpringBoot et SpringMVC Dec 29, 2023 am 11:02 AM

SpringBoot et SpringMVC sont tous deux des frameworks couramment utilisés dans le développement Java, mais il existe des différences évidentes entre eux. Cet article explorera les fonctionnalités et les utilisations de ces deux frameworks et comparera leurs différences. Tout d’abord, découvrons SpringBoot. SpringBoot a été développé par l'équipe Pivotal pour simplifier la création et le déploiement d'applications basées sur le framework Spring. Il fournit un moyen rapide et léger de créer des fichiers exécutables autonomes.

Comment SpringBoot personnalise Redis pour implémenter la sérialisation du cache Comment SpringBoot personnalise Redis pour implémenter la sérialisation du cache Jun 03, 2023 am 11:32 AM

1. Personnalisez RedisTemplate1.1, mécanisme de sérialisation par défaut RedisAPI. L'implémentation du cache Redis basée sur l'API utilise le modèle RedisTemplate pour les opérations de mise en cache des données. Ici, ouvrez la classe RedisTemplate et affichez les informations sur le code source de la classe. Déclarer la clé, diverses méthodes de sérialisation de la valeur, la valeur initiale est vide @NullableprivateRedisSe

Comment obtenir la valeur dans application.yml au Springboot Comment obtenir la valeur dans application.yml au Springboot Jun 03, 2023 pm 06:43 PM

Dans les projets, certaines informations de configuration sont souvent nécessaires. Ces informations peuvent avoir des configurations différentes dans l'environnement de test et dans l'environnement de production, et peuvent devoir être modifiées ultérieurement en fonction des conditions commerciales réelles. Nous ne pouvons pas coder en dur ces configurations dans le code. Il est préférable de les écrire dans le fichier de configuration. Par exemple, vous pouvez écrire ces informations dans le fichier application.yml. Alors, comment obtenir ou utiliser cette adresse dans le code ? Il existe 2 méthodes. Méthode 1 : Nous pouvons obtenir la valeur correspondant à la clé dans le fichier de configuration (application.yml) via le ${key} annoté avec @Value. Cette méthode convient aux situations où il y a relativement peu de microservices. Méthode 2 : En réalité. projets, Quand les affaires sont compliquées, la logique

Protection contre les scripts intersites (XSS) et la falsification de requêtes intersites (CSRF) dans Laravel Protection contre les scripts intersites (XSS) et la falsification de requêtes intersites (CSRF) dans Laravel Aug 13, 2023 pm 04:43 PM

Protection contre les scripts intersites (XSS) et la falsification de requêtes intersites (CSRF) dans Laravel Avec le développement d'Internet, les problèmes de sécurité des réseaux sont devenus de plus en plus graves. Parmi eux, Cross-SiteScripting (XSS) et Cross-SiteRequestForgery (CSRF) sont l'une des méthodes d'attaque les plus courantes. Laravel, en tant que framework de développement PHP populaire, offre aux utilisateurs une variété de mécanismes de sécurité

See all articles