Partage de technologie

Question 50 de l'entretien frontal (Quelles mesures de sécurité frontales courantes peuvent empêcher les attaques CSRF ?)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Insérer la description de l'image ici
Afin de prévenir les attaques CSRF (Cross-Site Request Forgery), les mesures de sécurité courantes suivantes peuvent être prises lors du développement front-end :

1. Utilisez le jeton CSRF

C’est l’un des mécanismes de défense les plus couramment utilisés.

  • Générer un jeton: Une fois l'utilisateur connecté, le serveur génère un jeton CSRF aléatoire et imprévisible et le stocke côté serveur. En même temps, il est envoyé au client via l'en-tête Set-Cookie et stocké dans le cookie de l'utilisateur.

  • Jeton intégré au formulaire: Dans chaque formulaire HTML nécessitant une protection, ajoutez un champ masqué (<input type="hidden">), sa valeur est définie sur le jeton CSRF lu à partir du cookie.

  • Vérifier le jeton : Lorsque le formulaire est soumis, le backend recevra les données du formulaire et le jeton dans le cookie (en raison de la politique de même origine, le navigateur enverra automatiquement le cookie). Le côté serveur vérifie si le Token sous le formulaire est cohérent avec le Token stocké côté serveur ou dans la Session. S'ils sont incohérents, la demande est rejetée.

2. Vérifiez le référent HTTP et l'en-tête d'origine

Bien qu'il ne soit pas totalement fiable car le Referer et l'Origin peuvent être falsifiés ou manquants, il peut toujours être utilisé comme moyen auxiliaire dans certains scénarios.

  • Vérifier le référent : Vérifiez le champ Referer dans l'en-tête de la requête HTTP pour vous assurer que la requête est initiée à partir du nom de domaine attendu. Il convient cependant de noter que cette méthode présente des limites. Par exemple, dans une demande de rétrogradation de HTTPS vers HTTP, le Referer ne sera pas envoyé.

  • Vérifier l'en-tête d'origine: Semblable à Referer, l'en-tête Origin fournit des informations sur la source de la requête, mais n'est envoyé que lors de l'utilisation de XMLHttpRequest ou de l'API Fetch.

3. Utilisez l'attribut SameSite Cookie

Pour les cookies qui ne nécessitent pas d'accès intersites, l'attribut SameSite peut être défini pour améliorer la sécurité.

  • SameSite=Lax: Le cookie n'est envoyé que dans les requêtes sur le même site, protégeant partiellement contre CSRF.
  • SameSite=Strict: Les cookies ne sont envoyés qu'au sein d'un même site et d'une même page de navigation, offrant une protection renforcée, mais peuvent affecter certaines fonctions inter-sous-domaines attendues.
  • SameSite=Aucun: Doit être utilisé avec l'attribut Secure pour les cookies qui doivent être intersites pour s'adapter aux exigences des navigateurs modernes.

4. Vérification de l'en-tête de demande personnalisée

Ajoutez un en-tête HTTP personnalisé à la requête AJAX (commeX-Requested-With: XMLHttpRequest ), puis vérifiez l'existence et la valeur de cet en-tête côté serveur. Étant donné que JavaScript peut définir librement l'en-tête de XMLHttpRequest, contrairement à la soumission de formulaire ordinaire, cela peut distinguer les requêtes initiées par des scripts.

Exemple de code (implémentation du jeton CSRF) :

Côté serveur (pseudocode):

// 生成并设置Token
function generateCsrfToken() {
    return crypto.randomBytes(32).toString('hex');
}

app.post('/login', (req, res) => {
    const token = generateCsrfToken();
    res.cookie('csrfToken', token, { httpOnly: true, secure: true, sameSite: 'strict' });
    // 存储token到session或其他存储机制
});

app.post('/submitForm', (req, res) => {
    if (req.body.csrfToken === req.cookies.csrfToken) {
        // 请求合法,处理逻辑...
    } else {
        // CSRF攻击检测,拒绝请求
        res.status(403).send('Forbidden');
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

HTML frontal:

<form action="/submitForm" method="POST">
    <!-- 其他表单字段... -->
    <input type="hidden" name="csrfToken" value="{{csrfToken}}">
    <button type="submit">Submit</button>
</form>
  • 1
  • 2
  • 3
  • 4
  • 5

Veuillez noter que le code ci-dessus n'est qu'un exemple et que l'application réelle doit être ajustée en fonction du framework backend et du langage utilisé.