Σε αυτό το άρθρο του οδηγού Spring Security, θα επιθεωρήσουμε το διακριτικό Spring Security CSRF ή απλά γνωστό ως διακριτικό csrf. Θα εξετάσουμε τις διάφορες διαθέσιμες επιλογές με το Spring Security CSRF.
Άνοιξη Security CSRF Token
Το CSRF είναι μια επίθεση που εξαπατά τον πελάτη να υποβάλει ένα κακόβουλο αίτημα. Με τη βοήθεια του CSRF, επιτρέπει στους εισβολείς να παραβιάζουν την ταυτότητα και τους αφήνει να εκτελούν μη εξουσιοδοτημένη εργασία για λογαριασμό του χρήστη. Για εφαρμογές Ιστού, τα προγράμματα περιήγησης περιλαμβάνουν ορισμένες κρίσιμες λεπτομέρειες που περιλαμβάνουν:
- Διαπιστευτήρια.
- Πληροφορίες cookie.
- Πληροφορίες συνεδρίας χρήστη.
- Διεύθυνση IP κ.λπ.
Επομένως, εάν έχουμε ήδη ελέγξει την ταυτότητα του χρήστη σε έναν ιστότοπο, αυτό καθιστά πραγματικά δύσκολο να γίνει διάκριση μεταξύ νόμιμου και πλαστού αιτήματος. Η ασφάλεια ελατηρίου παρέχει διάφορες δυνατότητες που βοηθούν στο χειρισμό αυτού του είδους των επιθέσεων. Πριν μπούμε σε περισσότερες λεπτομέρειες, ας δούμε πώς θα συμβεί η επίθεση CSRF.

2. Πρόληψη CSRF
Υπάρχουν πολλές επιλογές που μπορούμε να εφαρμόσουμε για να χειριστούμε αυτήν την επίθεση CSRF. Εδώ είναι μερικές από τις γνωστές επιλογές:
- Μυστικό μπισκότο.
- HTTPS POST.
- Χρησιμοποιήστε τη μέθοδο POST και όχι GET.
- Επανεγγραφή URL.
Όλοι μπορούν να προσθέσουν ορισμένους πρόσθετους ελέγχους, αλλά δεν αποτρέπουν αυτούς τους τύπους επιθέσεων και μπορεί να χρειαστούμε κάποια πρόσθετα βήματα/ελέγχους για να το χειριστούμε.
3. Μοτίβο διακριτικού συγχρονιστή
Το Spring Security CSRF Token παρέχει προστασία από αυτές τις επιθέσεις χρησιμοποιώντας το μοτίβο διακριτικού συγχρονιστή. Ας δούμε πώς λειτουργεί αυτό το μοτίβο για να μας βοηθήσει να ασφαλίσουμε το αίτημα HTTP.
- Κάθε αίτημα HTTP απαιτεί, εκτός από το cookie περιόδου λειτουργίας, μια ασφαλή τυχαία παραγόμενη τιμή που ονομάζεται διακριτικό CSRF.
- Ο διακομιστής αποθηκεύει αυτό το διακριτικό στο τέλος του διακομιστή και το μεταβιβάζει επίσης στον πελάτη.
- Αυτό το διακριτικό CSRF πρέπει να υπάρχει στο αίτημα HTTP που προέρχεται από τον πελάτη.
- Όταν υποβάλλεται ένα αίτημα HTTP, ο διακομιστής πρέπει να αναζητήσει το αναμενόμενο διακριτικό CSRF και να το συγκρίνει με το πραγματικό διακριτικό CSRF στο αίτημα HTTP.
- Εάν οι τιμές του διακριτικού δεν ταιριάζουν και στις δύο πλευρές, το αίτημα αντιμετωπίζεται ως πιθανό πλαστό αίτημα και θα απορριφθεί.
- Δεν περιλαμβάνουμε το διακριτικό CSRF ασφάλειας ελατηρίου στο αίτημα GET, καθώς μπορεί εύκολα να διαρρεύσει.
Αυτό το πρόσθετο διακριτικό CSRF θα πρέπει να βρίσκεται σε ένα μέρος του αιτήματος HTTP που δεν περιλαμβάνεται αυτόματα από το πρόγραμμα περιήγησης.
Το διακριτικό CSRF δεν αποτελεί μέρος του cookie, καθώς το πρόγραμμα περιήγησης συμπεριέλαβε αυτόματα cookies στο αίτημα HTTP. Αυτό προσθέτει ένα άλλο επίπεδο ασφάλειας, καθώς μας ανάγκασε να στείλουμε το διακριτικό στο αίτημα HTTP προσθέτοντάς το στο ωφέλιμο φορτίο.
Ας δούμε πώς λειτουργεί αυτή η διαδικασία για να μας βοηθήσει να αποφύγουμε την επίθεση.

Αυτό το διακριτικό CSRF πρέπει να υποβάλλεται στον διακομιστή σε κάθε αίτημα HTTP που αλλάζει κατάσταση (PATCH, POST, PUT και DELETE εκτός από το GET). Αν σε ενδιαφέρει, δες το
CsrfFilter
τάξη για να κατανοήσει πώς δημιουργεί και επικυρώνει το διακριτικό.
Με το διακριτικό CSRF, έτσι θα μοιάζει το αίτημα:
POST /refund HTTP/1.1
Host: javadevjournal.com
Cookie: JSESSIONID=randomid;Domain=javadevjournal.com; Secure; HttpOnly
Content-Type: application/x-www-form-urlencoded
amount=340.00&_csrf=4bfd1575-3ad1-4d21-96c7-4ef2d9f86721
Με κάθε αίτημα POST, προσθέτουμε _csrf
παράμετρος με μια τυχαία τιμή και θα επαληθεύσει αυτήν την τιμή με το διακριτικό που είναι αποθηκευμένο στην πλευρά του διακομιστή. Δεν θα είναι εύκολο για τον κακόβουλο ιστότοπο να μαντέψει τη σωστή τιμή για το _csrf
παράμετρος.
Ένας αναδυόμενος τρόπος προστασίας από επιθέσεις CSRF είναι να προσδιορίσετε το Χαρακτηριστικό SameSite σε μπισκότα. Ένας διακομιστής μπορεί να καθορίσει το
SameSite
χαρακτηριστικό κατά τη ρύθμιση ενός cookie ώστε να δείχνει ότι το cookie δεν πρέπει να αποστέλλεται όταν προέρχεται από εξωτερικούς ιστότοπους.
3.1 Ενεργοποίηση CSRF Token στο Spring Security
Το Spring Security παρέχει υποστήριξη OOTB για το διακριτικό CSRF και είναι ενεργοποιημένο από προεπιλογή. Δεν χρειαζόμαστε συγκεκριμένα βήματα για την ενεργοποίηση αυτής της δυνατότητας, ωστόσο μπορείτε να απενεργοποιήσετε αυτήν τη δυνατότητα csrf().disable()
στην κλάση διαμόρφωσης ασφαλείας Spring.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
Με την προεπιλεγμένη ρύθμιση, αν κοιτάξετε τον πηγαίο κώδικα της σελίδας, θα δείτε το _csrf
η παράμετρος προστίθεται αυτόματα στη φόρμα από την ασφάλεια Spring. Εδώ είναι η πηγή HTML για τη σελίδα εγγραφής μας Εκμάθηση ανοιξιάτικης ασφάλειας.
<form action="/register" method="post">
<input type="hidden" name="_csrf" value="6c5e7122-b45a-4255-99a4-ec162b156ed6" />
<div class="row">
<!-- /.col -->
<div class="col-4">
<button type="submit" class="btn btn-primary btn-block">Register</button>
</div>
<!-- /.col -->
</div>
</form>
3.2. Πότε να χρησιμοποιείτε προστασία CSRF
Θα πρέπει να ενεργοποιήσουμε το Spring Security CSRF για τις ακόλουθες περιπτώσεις χρήσης:
- Εάν ένας κανονικός χρήστης ενεργοποιήσει το αίτημα.
- Σε περίπτωση που υποβληθεί σε επεξεργασία από το πρόγραμμα περιήγησης.
Μπορούμε να το απενεργοποιήσουμε σε περίπτωση που κάποιος πελάτης εκτός του προγράμματος περιήγησης ή του χρήστη ξεκινήσει και επεξεργαστεί το αίτημα.
4. Αίτημα Ajax και JSON
Σε περίπτωση που χρησιμοποιούμε αίτημα JSON ή Ajax, δεν είναι δυνατό να συμπεριλάβουμε το διακριτικό CSRF ως παράμετρο αιτήματος. Το Spring Security παρέχει τις ακόλουθες επιλογές για την αποστολή του διακριτικού.
4.1. Meta Tag
Μια επιλογή είναι να συμπεριλάβετε το διακριτικό ως μετα-ετικέτα. Το HTML μπορεί να μοιάζει κάπως έτσι:
<head>
<meta name="_csrf" content="4bfd1575-3ad1-4d21-76yh-5ygfuyd9f86721"/>
<meta name="_csrf_header" content="X-CSRF-TOKEN"/>
<!-- ... -->
</head>
4.2. AJAX αποστολή CSRF Token
Για JQuery ή παρόμοιο πλαίσιο, μπορούμε να χρησιμοποιήσουμε κάτι σαν:
$(function () {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
4.3. Αυτόματη συμπερίληψη διακριτικού CSRF
Με τη βιβλιοθήκη ετικετών φόρμας Spring, Φύλλο θυμαριούή οποιαδήποτε άλλη τεχνολογία προβολής που ενσωματώνεται με RequestDataValueProcessor
θα περιλαμβάνει αυτόματα το πραγματικό CSRF
διακριτικό για μη ασφαλή μέθοδο HTTP. Σε περίπτωση που δεν χρησιμοποιείτε αυτές τις βιβλιοθήκες ετικετών, μπορούμε εύκολα να συμπεριλάβουμε το διακριτικό με το csrfInput
ετικέτα:
<form method="post" action="register">
<sec:csrfInput />
</form>
Υπάρχουν ορισμένες περιπτώσεις χρήσης όπου δεν θα μπορείτε να χρησιμοποιήσετε τις υποστηριζόμενες βιβλιοθήκες ετικετών ή δεν μπορείτε να τις συμπεριλάβετε csrfInput
ετικέτα, θυμηθείτε ότι αυτό το διακριτικό CSRF εκτίθεται ως HttpServletRequest
χαρακτηριστικό που ονομάζεται _csrf
. Μπορούμε να συμπεριλάβουμε το διακριτικό με παρόμοια προσέγγιση:
<form action="/register" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
5. Αιτήσεις CSRF και Απάτριδων
Εάν ένας χρήστης δεν χρειάζεται να εκτελέσει καμία ενέργεια στο πρόγραμμα περιήγησης Ιστού για ένα αίτημα, είναι πιθανό να εξακολουθεί να είναι ευάλωτος σε επιθέσεις CSRF. Αυτό είναι πολύ σημαντικό σε περίπτωση που χρησιμοποιούμε έλεγχος ταυτότητας cookie συνεδρίαςn. Για αυτό το είδος ελέγχου ταυτότητας, θα πρέπει να ενεργοποιήσουμε τη λειτουργία διακριτικού CSRF ασφαλείας Spring.
Εάν χρησιμοποιούμε μηχανισμό διακριτικού που βασίζεται στο JWT, δεν χρειαζόμαστε προστασία CSRF και πρέπει να απενεργοποιήσουμε.
Μπορούμε να προσαρμόσουμε CsrfTokenRepository
προσέγγιση για την προσθήκη προστασίας CSRF για τις ανιθαγενείς εφαρμογές.
5.1. Προσαρμοσμένο CsrfTokenRepository
Η ασφάλεια ελατηρίου αποθηκεύει από προεπιλογή το αναμενόμενο διακριτικό CSRF στο HttpSession
χρησιμοποιώντας HttpSessionCsrfTokenRepository
. Για εφαρμογή χωρίς ιθαγένεια, μπορούμε να διαμορφώσουμε μια προσαρμογή CsrfTokenRepository
να επιμείνει το CsrfToken
σε ένα μπισκότο. Μπορούμε να χρησιμοποιήσουμε CookieCsrfTokenRepository
γράψτε σε ένα cookie με όνομα XSRF-TOKEN
και διαβάστε το από μια κεφαλίδα με το όνομα X-XSRF-TOKEN
ή την παράμετρο HTTP _csrf
. Μπορείτε να διαμορφώσετε το αποθετήριο προσαρμοσμένων διακριτικών ως:
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
http
.csrf(csrf - >
csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
}
}
6. Επιφυλάξεις
Θα πρέπει να γνωρίζουμε ορισμένες προειδοποιήσεις κατά τη χρήση του CSRF στο Spring Security.
6.1. Χρονικό όριο περιόδου λειτουργίας
Όπως γνωρίζουμε το διακριτικό CSRF αποθηκεύεται στο HTTPSession, οπότε μόλις λήξει η περίοδος λειτουργίας, AcessDeniedHandler
θα πάρει ένα InvalidCsrfTokenException
. Με αυτό, ο πελάτης θα λάβει άρνηση πρόσβασης σε μήνυμα ή σελίδα. Ακολουθούν ορισμένες από τις επιλογές για τον μετριασμό αυτού του ζητήματος:
- Χρησιμοποιήστε την κλήση Ajax για να ζητήσετε ένα διακριτικό CSRF κατά την υποβολή της φόρμας. Αυτό θα λάβει το διακριτικό ενημέρωσης και θα το υποβάλει ως μέρος του ωφέλιμου φορτίου αιτήματος.
- Μπορούμε επίσης να δημιουργήσουμε μια λειτουργία βασισμένη στο Ajax για να ελέγξουμε τη συνεδρία και να ενημερώσουμε τον πελάτη να την ανανεώσει πριν υποβάλει τη φόρμα.
- Μπορούμε επίσης να αποθηκεύσουμε το διακριτικό CSRF σε ένα cookie (Παρακαλούμε να γνωρίζετε ότι δημιουργεί κάποιο πρόβλημα ασφαλείας)
6.2. Σύνδεση
Θα πρέπει να προστατεύσουμε τη φόρμα σύνδεσης από επιθέσεις CSRF για οποιοδήποτε πλαστό αίτημα σύνδεσης. Η ασφάλεια Spring παρέχει υποστήριξη OOTB για σύνδεση.
6.3. Αποσυνδέομαι
Εάν η δυνατότητα CSRF είναι ενεργοποιημένη στο Spring Security, προσθέτει έναν έλεγχο ασφαλείας ενεργοποιώντας LogoutFilter
για επεξεργασία μόνο HTTP POST. Αυτό θα διασφαλίσει ότι μόνο έγκυρος χρήστης με έγκυρο διακριτικό επιτρέπεται να στείλει αίτημα αποσύνδεσης.
Δεν συνιστάται η ενεργοποίηση της αποσύνδεσης χρησιμοποιώντας τη μέθοδο GET, καθώς αυτό εκθέτει τον χρήστη σας για εκμετάλλευση.
Περίληψη
Σε αυτό το άρθρο, εξερευνήσαμε τις διάφορες δυνατότητες της προστασίας CSRF με την ασφάλεια Spring. Είδαμε ότι αυτή η δυνατότητα ασφαλείας είναι ενεργή από προεπιλογή στην ασφάλεια Spring. Είδαμε επίσης διαφορετικές επιλογές για την προσαρμογή της δυνατότητας στο Spring Security. Όπως πάντα, ο πηγαίος κώδικας για αυτήν τη σειρά είναι διαθέσιμος στο δικό μας Αποθετήριο GitHub.