[๋ณด์•ˆ][CSRF]๐Ÿ”’ CSRF ๊ณต๊ฒฉ? ์ด์ œ๋Š” ์ฒ ์ €ํžˆ ๋ง‰์•„๋ณด์ž! ๐Ÿš€

๊น€์ƒ์šฑยท2024๋…„ 12์›” 8์ผ
post-thumbnail

๐Ÿ’ป CSRF (Cross-Site Request Forgery)

CSRF๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ ์ทจ์•ฝ์  ์ค‘ ํ•˜๋‚˜๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ์‹ ๋ขฐํ•˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ณต๊ฒฉ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋งŒ๋“œ๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ณต๊ฒฉ์ž๋Š” ํ”ผํ•ด์ž์˜ ๊ถŒํ•œ์œผ๋กœ ์•…์˜์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


1๏ธโƒฃ CSRF์˜ ์ •์˜

Cross-Site Request Forgery (CSRF)๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ๋œ ์„ธ์…˜ ์ƒํƒœ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์š”์ฒญ์„ ๊ณต๊ฒฉ์ž๊ฐ€ ์œ„์กฐํ•˜์—ฌ, ์‚ฌ์šฉ์ž์˜ ์˜์ง€์™€ ์ƒ๊ด€์—†์ด ๊ณต๊ฒฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค.


2๏ธโƒฃ ์ž‘๋™ ์›๋ฆฌ

CSRF ๊ณต๊ฒฉ์€ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ƒํƒœ์™€ ๋ธŒ๋ผ์šฐ์ €์˜ ์‹ ๋ขฐ์„ฑ์„ ์•…์šฉํ•ฉ๋‹ˆ๋‹ค.

  1. ๐Ÿ”’ ์ธ์ฆ๋œ ์„ธ์…˜ ์•…์šฉ
    ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•œ ์ƒํƒœ์—์„œ ์ฟ ํ‚ค๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ๋™์ผํ•œ ๋„๋ฉ”์ธ์— ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์ž๋™์œผ๋กœ ์ฟ ํ‚ค๋ฅผ ์ฒจ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

  2. ๐Ÿ“ฉ ์œ„์กฐ๋œ ์š”์ฒญ ์ „์†ก
    ๊ณต๊ฒฉ์ž๊ฐ€ ์œ„์กฐ๋œ ์š”์ฒญ์„ ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ์‹คํ–‰ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.


3๏ธโƒฃ ๊ณต๊ฒฉ ์‹œ๋‚˜๋ฆฌ์˜ค

  1. ์‚ฌ์šฉ์ž๊ฐ€ example.com์— ๋กœ๊ทธ์ธํ•ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ ํ›„ ์„ธ์…˜ ์ฟ ํ‚ค๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  2. ๊ณต๊ฒฉ์ž๊ฐ€ ์•…์˜์ ์ธ ์›น์‚ฌ์ดํŠธ malicious.com์„ ๋งŒ๋“ค๊ณ , CSRF ๊ณต๊ฒฉ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•œ HTML์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
    <img src="https://example.com/transfer?amount=1000&to=attacker_account">
  3. ์‚ฌ์šฉ์ž๊ฐ€ malicious.com์„ ๋ฐฉ๋ฌธํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ž๋™์œผ๋กœ example.com์— ์ฟ ํ‚ค๋ฅผ ํฌํ•จํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์ด๋ฏธ์ง€์˜ src๋ฅผ ํ†ตํ•ด example.com ํŽ˜์ด์ง€์— ์ ‘๊ทผ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  4. ๊ฒฐ๊ณผ์ ์œผ๋กœ, example.com ์„œ๋ฒ„๋Š” ์š”์ฒญ์„ ์ •๋‹นํ•œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์˜จ ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ณต๊ฒฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์ž‘์—…์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

4๏ธโƒฃ ์ฃผ์š” ํ”ผํ•ด

  • ๐Ÿ’ธ ๊ณ„์ขŒ ์ด์ฒด
  • ๐Ÿ”‘ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ
  • ๐Ÿ—‘๏ธ ๋ฐ์ดํ„ฐ ์‚ญ์ œ
  • ๐Ÿ›ก๏ธ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ์•…์šฉ

5๏ธโƒฃ CSRF ๋ฐฉ์–ด ๋ฐฉ๋ฒ•

5.1 ๐Ÿ” CSRF Token ์‚ฌ์šฉ

  • ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์— ๊ณ ์œ ํ•œ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ๋Š” ๋ชจ๋“  ์š”์ฒญ์— ์ด ํ† ํฐ์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„๋Š” ์š”์ฒญ ์‹œ ํ•ด๋‹น ํ† ํฐ์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

Spring Security ๊ตฌํ˜„ ์˜ˆ์‹œ:
1. HTML์— CSRF ํ† ํฐ ์‚ฝ์ž…:

<input type="hidden" name="_csrf" value="ํ† ํฐ๊ฐ’">
  1. ์„œ๋ฒ„์—์„œ ํ† ํฐ ๊ฒ€์ฆ:
    ์„œ๋ฒ„๋Š” ์š”์ฒญ์˜ ํ† ํฐ๊ณผ ์„ธ์…˜์— ์ €์žฅ๋œ ํ† ํฐ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

5.2 ๐Ÿงพ Referer/Origin ๊ฒ€์ฆ

  • ์š”์ฒญ์˜ ํ—ค๋”์—์„œ Referer ๋˜๋Š” Origin ๊ฐ’์„ ํ™•์ธํ•˜์—ฌ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ถœ์ฒ˜์—์„œ ์˜จ ์š”์ฒญ์ธ์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
    if (!request.getHeader("Referer").startsWith("https://example.com")) {
        throw new SecurityException("CSRF detected!");
    }
  • โš ๏ธ ์ฃผ์˜: ์ผ๋ถ€ ๋ธŒ๋ผ์šฐ์ €๋‚˜ ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ Referer๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด ์‹ ๋ขฐ์„ฑ์ด ๋‚ฎ์„ ์ˆ˜ ์žˆ์Œ.
  • ์ฟ ํ‚ค์— SameSite ์†์„ฑ์„ ์„ค์ •ํ•˜์—ฌ, ๋™์ผํ•œ ์‚ฌ์ดํŠธ์—์„œ ๋ฐœ์ƒํ•œ ์š”์ฒญ์—์„œ๋งŒ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•˜๋„๋ก ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
    Set-Cookie: sessionId=abc123; SameSite=Strict;

5.4 ๐Ÿ›ก๏ธ ์‚ฌ์šฉ์ž ์ธ์ฆ ๊ฐ•ํ™”

  • CSRF ๊ณต๊ฒฉ์œผ๋กœ ์ค‘์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ์ถ”๊ฐ€์ ์ธ ์ธ์ฆ(์˜ˆ: OTP, ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ)์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

6๏ธโƒฃ CSRF vs XSS

๊ตฌ๋ถ„CSRFXSS
๊ณต๊ฒฉ ๋ฐฉ์‹ํ”ผํ•ด์ž์˜ ๊ถŒํ•œ์„ ์•…์šฉํ•ด ์„œ๋ฒ„์— ์•…์˜์  ์š”์ฒญ์„ ๋ณด๋ƒ„ํ”ผํ•ด์ž ๋ธŒ๋ผ์šฐ์ €์—์„œ ์•…์˜์  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰
๋Œ€์ƒ์„œ๋ฒ„ํด๋ผ์ด์–ธํŠธ
์š”๊ตฌ ์กฐ๊ฑดํ”ผํ•ด์ž๊ฐ€ ์ธ์ฆ๋œ ์ƒํƒœ๋กœ ์š”์ฒญํ•ด์•ผ ํ•จ๋ณ„๋„์˜ ์ธ์ฆ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Œ

7๏ธโƒฃ CSRF ๋ฐฉ์–ด ์ „๋žต ์š”์•ฝ

  1. โœ… CSRF ํ† ํฐ ์ƒ์„ฑ ๋ฐ ๊ฒ€์ฆ
  2. โœ… Referer/Origin ํ—ค๋” ๊ฒ€์ฆ
  3. โœ… ์ฟ ํ‚ค์˜ SameSite ์†์„ฑ ์„ค์ •
  4. โœ… ๋ฏผ๊ฐํ•œ ์ž‘์—…์— ์ถ”๊ฐ€ ์ธ์ฆ ์š”๊ตฌ
  5. โœ… ์ตœ์†Œํ•œ์˜ CORS ํ—ˆ์šฉ

8๏ธโƒฃ Spring Security์˜ CSRF ๋ณดํ˜ธ

Spring Security๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ CSRF ๋ณดํ˜ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  1. ๊ธฐ๋ณธ ์„ค์ •:

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().enable();
        }
    }
  2. ์ปค์Šคํ„ฐ๋งˆ์ด์ง•:
    ํŠน์ • ์š”์ฒญ์— ๋Œ€ํ•ด CSRF ๋ณดํ˜ธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    http.csrf().ignoringAntMatchers("/api/**");

9๏ธโƒฃ ๊ฒฐ๋ก 

CSRF๋Š” ์‚ฌ์šฉ์ž์˜ ์‹ ๋ขฐ๋ฅผ ์•…์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ๊ณต๊ฒฉํ•˜๋Š” ๋งค์šฐ ์œ„ํ—˜ํ•œ ๊ธฐ๋ฒ•์ด์ง€๋งŒ, CSRF ํ† ํฐ, SameSite ์ฟ ํ‚ค ์„ค์ •, ์ถ”๊ฐ€ ์ธ์ฆ ๋“ฑ์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐฉ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CSRF ๋ฐฉ์–ด๋ฅผ ์ฒ ์ €ํžˆ ๊ตฌํ˜„ํ•˜์—ฌ, ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿš€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ์„ ์œ„ํ•ด CSRF ๋ฐฉ์–ด๋Š” ํ•„์ˆ˜!

0๊ฐœ์˜ ๋Œ“๊ธ€