הגנה על CSRF עם MVC קפיץ ו Thymeleaf

1. הקדמה

Thymeleaf הוא מנוע תבנית Java לעיבוד וליצירת HTML, XML, JavaScript, CSS וטקסט רגיל. לקבלת מבוא ל- Thymeleaf ו- Spring, עיין בכתיבה זו.

במאמר זה נדון כיצד למנוע התקפות זיוף בקשות חוצות אתרים (CSRF) באביב MVC עם יישום Thymeleaf. ליתר דיוק, נבדוק התקפת CSRF לשיטת HTTP POST.

CSRF היא התקפה שמאלצת את משתמש הקצה לבצע פעולות לא רצויות ביישום אינטרנט בו מאומת כעת.

2. תלות Maven

ראשית, הבה נראה את התצורות הנדרשות לשילוב Thymeleaf עם Spring. ה קפיץ עליון ספרייה נדרשת בתלות שלנו:

 org.thymeleaf thymeleaf 3.0.11. RELEASE org.thymeleaf thymeleaf-spring5 3.0.11. RELEASE 

שים לב שעבור פרויקט אביב 4, קפיץ עליון 4 יש להשתמש בספריה במקום 5. אביב קפיץ. הגרסה האחרונה של התלות עשויה להימצא כאן.

יתר על כן, על מנת להשתמש באבטחת אביב, עלינו להוסיף את התלות הבאה:

 org.springframework.security spring-security-web 5.2.3.RELEASE org.springframework.security spring-security-config 5.2.3.RELEASE 

הגרסאות האחרונות של שתי ספריות הקשורות לאבטחת Spring זמינות כאן וכאן.

3. תצורת Java

בנוסף לתצורה של Thymeleaf המכוסה כאן, עלינו להוסיף תצורה עבור Spring Security. על מנת לעשות זאת, עלינו ליצור את הכיתה:

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity (secureEnabled = true, prePostEnabled = true) מחלקה ציבורית WebMVCSecurity מרחיב את WebSecurityConfigurerAdapter {@Bean @Override AuthenticationManager public authenticationManagerBean () זורק ExceptionBent (חזר). } תצורת הריק המוגנת על ידי @Override (AuthenticationManagerBuilder auth) זורקת Exception {auth.inMemoryAuthentication () .withUser ("user1"). סיסמה ("{noop} user1Pass") .authorities ("ROLE_USER"); } @ הגדרת תצורה חלולה ציבורית של @Override (WebSecurity web) זורקת חריג {web.ignoring (). AntMatchers ("/ resources / **"); } תצורת הריק המוגנת על ידי @Override (HttpSecurity http) זורקת חריג {http .authorizeRequests () .anyRequest () .authenticated () .and () .httpBasic (); }}

לפרטים נוספים ותיאור תצורת האבטחה, אנו מתייחסים לסדרת אבטחה עם אביב.

הגנת CSRF מופעלת כברירת מחדל עם תצורת Java. על מנת להשבית תכונה שימושית זו עלינו להוסיף זאת פנימה הגדר (...) שיטה:

.csrf (). השבת ()

בתצורת XML עלינו לציין את הגנת CSRF באופן ידני, אחרת זה לא יעבוד:

שימו לב גם שאם אנו משתמשים בדף כניסה עם טופס כניסה, עלינו לכלול את אסימון CSRF תמיד בטופס הכניסה כפרמטר מוסתר באופן ידני בקוד:

עבור הטפסים הנותרים, אסימון CSRF יתווסף אוטומטית לטפסים עם קלט מוסתר:

4. תצורת תצוגות

בואו נמשיך לחלק העיקרי של קבצי HTML עם פעולות טופס ויצירת הליך בדיקה. בתצוגה הראשונה אנו מנסים להוסיף לרשימה תלמיד חדש:

   הוסף סטודנט 

בתצוגה זו אנו מוסיפים תלמיד לרשימה, על ידי מתן תְעוּדַת זֶהוּת, שֵׁם, מִין ו אֲחוּזִים (אופציונלי, כאמור באימות הטופס). לפני שנוכל לבצע טופס זה, עלינו לספק מִשׁתַמֵשׁ ו סיסמה, כדי לאמת אותנו ביישום אינטרנט.

4.1. בדיקת התקפות CSRF בדפדפן

כעת נמשיך לתצוגת ה- HTML השנייה. מטרתו היא לנסות לבצע התקפת CSRF:

אנו יודעים שכתובת האתר לפעולה היא // localhost: 8080 / spring-thymeleaf / saveStudent. ההאקר רוצה לגשת לדף זה כדי לבצע התקפה.

על מנת לבדוק, פתח את קובץ ה- HTML בדפדפן אחר, מבלי להתחבר לאפליקציה. כשתנסה להגיש את הטופס, נקבל את הדף:

בקשתנו נדחתה מכיוון ששלחנו בקשה ללא אסימון CSRF.

לידיעתך, נעשה שימוש בהפעלת HTTP על מנת לאחסן אסימון CSRF. כאשר נשלחת הבקשה, אביב משווה אסימון שנוצר עם האסימון המאוחסן בהפעלה, על מנת לאשר שהמשתמש לא נפרץ.

4.2. בדיקת התקפה של JUnit CSRF

אם אינך רוצה לבדוק התקפת CSRF באמצעות דפדפן, תוכל לעשות זאת גם באמצעות מבחן אינטגרציה מהיר; נתחיל בתצורת האביב למבחן זה:

@RunWith (SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration (classes = {WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class}) CsrfEnabledIntegrationTest {// תצורה} ציבורית בכיתה ציבורית

ועבר למבחנים בפועל:

@Test ציבורי בטל addStudentWithoutCSRF () זורק חריג {mockMvc.perform (פוסט ("/ saveStudent"). ContentType (MediaType.APPLICATION_JSON) .param ("id", "1234567"). Param ("שם", "Joe") .param ("מגדר", "M"). עם (testUser ())). ו- Expect (סטטוס (). isForbidden ()); } @Test ציבורי בטל addStudentWithCSRF () זורק חריג {mockMvc.perform (פוסט ("/ saveStudent"). ContentType (MediaType.APPLICATION_JSON) .param ("id", "1234567"). Param ("שם", "Joe" ) .param ("מגדר", "M"). עם (testUser ()). עם (csrf ())). ו- Expect (סטטוס (). isOk ()); }

הבדיקה הראשונה תביא למעמד אסור בגלל אסימון ה- CSRF החסר, ואילו השני יבוצע כהלכה.

5. מסקנה

במאמר זה דנו כיצד למנוע התקפות CSRF באמצעות Spring Security ו- Thymeleaf.

ניתן למצוא את היישום המלא של מדריך זה בפרויקט GitHub - זהו פרויקט מבוסס Eclipse, כך שיהיה קל לייבא ולהפעיל אותו כפי שהוא.