์ธ์ฆ ๋ณด์•ˆ ๊ฐ•ํ™”

2024. 11. 29. 05:44ยทํ”„๋กœ์ ํŠธ/NolGoat

๊ฐœ์š”

ํ˜„์žฌ `Access` ํ† ํฐ์€ `๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€`์—, `Refresh` ํ† ํฐ์€ `์ฟ ํ‚ค`์— ์ €์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” `XSS` ๋ฐ `CSRF` ๊ณต๊ฒฉ์— ์˜ํ•œ ํ”ผํ•ด๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ•˜๊ณ , ์ ์šฉํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

์ฐธ๊ณ ) XSS์™€ CSRF ๊ณต๊ฒฉ

XSS (Cross-Site Scripting) ๊ณต๊ฒฉ

  • ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ํ† ํฐ์„ ํƒˆ์ทจํ•˜๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด `Http-Only` ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.
  • Http-Only ์ฟ ํ‚ค๋Š” ์Šคํฌ๋ฆฝํŠธ์˜ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

CSRF (Cross-Site Request Forgery) ๊ณต๊ฒฉ

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

 

ํ† ํฐ ๊ด€๋ฆฌ ๋ฐฉ์‹

Access ํ† ํฐ

  • Access ํ† ํฐ์€ ๋ณดํ†ต ์ค‘์š”ํ•œ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์š”์ฒญ์— ์‚ฌ์šฉ๋˜๋ฏ€๋กœ CSRF ๊ณต๊ฒฉ์— ์ƒ๋Œ€์ ์œผ๋กœ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด, Access ํ† ํฐ์€ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์ƒ๋Œ€์ ์œผ๋กœ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ XSS ๊ณต๊ฒฉ์œผ๋กœ ํ† ํฐ์ด ํƒˆ์ทจ๋˜๋”๋ผ๋„ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ์งง์•„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์‹œ๊ฐ„์ด ์ œํ•œ์ ์ด๋ฏ€๋กœ, ์ƒ๋Œ€์ ์œผ๋กœ ์œ„ํ—˜์ด ์ ์Šต๋‹ˆ๋‹ค.

 

Refresh ํ† ํฐ

  • Refresh ํ† ํฐ์€ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ๊ธธ์–ด ์ง์ ‘์ ์ธ ํƒˆ์ทจ์— ๋”์šฑ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ Http-Only ์ฟ ํ‚ค์— ์ €์žฅํ•˜์—ฌ XSS ๊ณต๊ฒฉ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
public Cookie createRefreshTokenCookie(String refreshToken) {
    Cookie refreshTokenCookie = new Cookie(REFRESH_TOKEN_COOKIE_NAME, refreshToken);
    refreshTokenCookie.setHttpOnly(true);
    refreshTokenCookie.setSecure(true);
    refreshTokenCookie.setPath("/");
    refreshTokenCookie.setMaxAge(REFRESH_TOKEN_COOKIE_EXPIRATION_TIME);
    return refreshTokenCookie;
}

ํ•˜์ง€๋งŒ CSRF ๊ณต๊ฒฉ์— ๋Œ€ํ•œ ๊ณ ๋ ค๋„ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด์— ๋Œ€ํ•œ ๋Œ€์‘ ๋ฐฉ์•ˆ๋„ ๊ณ ๋ฏผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

Refresh ํ† ํฐ CSRF ๊ณต๊ฒฉ ๋Œ€์‘ ๋ฐฉ์•ˆ

  1. `Referer` ํ—ค๋” ๊ฒ€์ฆ์„ ํ†ตํ•œ ๋„๋ฉ”์ธ ์ผ์น˜ ์—ฌ๋ถ€ ํ™•์ธ (โŒ)
    • Referer ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•ด ์š”์ฒญ ์ถœ์ฒ˜๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ํ—ค๋”๊ฐ€ ํ•ญ์ƒ ์กด์žฌํ•œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†๋‹ค๋Š” ์ ์—์„œ ๊ฒ€์ฆ ๋ฐฉ๋ฒ•์œผ๋กœ ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. `CSRF Random UUID`๋ฅผ ํ™œ์šฉํ•œ ํ—ค๋” ๊ฒ€์ฆ (โญ•)
    • Refresh ํ† ํฐ์ด ํ•„์š”ํ•œ ์š”์ฒญ๋งˆ๋‹ค ํด๋ผ์ด์–ธํŠธ๋Š” ๊ณ ์œ ํ•œ CSRF UUID๋ฅผ ํ—ค๋”์— ํฌํ•จํ•ด ๋ณด๋ƒ…๋‹ˆ๋‹ค.
    • ์„œ๋ฒ„๋Š” ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „์— ํ•ด๋‹น CSRF UUID๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ์ง€ ๊ฒ€์ฆํ•˜์—ฌ CSRF ๊ณต๊ฒฉ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์ž…๋‹ˆ๋‹ค.
    • ์ด ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•˜๊ฒŒ CSRF ๊ณต๊ฒฉ์˜ ํ”ผํ•ด๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ฉด์„œ๋„ ์ถ”๊ฐ€์ ์ธ ๋ณต์žก์„ฑ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ตฌํ˜„

  • `yml` ํŒŒ์ผ์—์„œ CSRF UUID ๊ฐ’์„ ๊ด€๋ฆฌ
spring:
  csrf:
    protection:
      uuid: ${CSRF_PROTECTION_UUID}

 

  • CSRF UUID ๊ฒ€์ฆ ๋กœ์ง
@Value("${spring.csrf.protection.uuid}")
private String csrfProtectionUuid;

public void verifyCsrfProtectionUuid(String csrfProtectionUuid) {
    if (!this.csrfProtectionUuid.equals(csrfProtectionUuid)) {
        throw new ApiException(INVALID_CSRF_PROTECTION_UUID);
    }
}

 

๊ฒฐ๊ณผ

Access ํ† ํฐ์€ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์—์„œ ๊ด€๋ฆฌํ•˜์—ฌ CSRF ๊ณต๊ฒฉ ์œ„ํ—˜์„ ์ค„์˜€๊ณ , Refresh ํ† ํฐ์€ Http-Only ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด XSS ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Refresh ํ† ํฐ์ด ํ•„์š”ํ•œ ์š”์ฒญ์—๋Š” CSRF Random UUID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CSRF ๊ณต๊ฒฉ์˜ ํ”ผํ•ด๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

'ํ”„๋กœ์ ํŠธ > NolGoat' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

์†Œ์…œ ๋กœ๊ทธ์ธ ํšŒ์› ํƒˆํ‡ด ๊ตฌํ˜„  (0) 2024.12.01
ํšจ์œจ์ ์ธ ํ† ํฐ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ Redis ๋„์ž…  (1) 2024.11.29
์ธ์ฆ์ด ํ•„์š”ํ•œ URL ๊ณตํ†ต ๊ด€๋ฆฌ  (0) 2024.11.27
Spring Security ์ธ์ฆ ํ•„ํ„ฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ  (0) 2024.11.27
์กฐํšŒ ๋ฐฉ์‹ ๊ฐœ์„  ๋ฐ ์ธ๋ฑ์Šค ์ˆ˜์ •  (0) 2024.11.26
'ํ”„๋กœ์ ํŠธ/NolGoat' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • ์†Œ์…œ ๋กœ๊ทธ์ธ ํšŒ์› ํƒˆํ‡ด ๊ตฌํ˜„
  • ํšจ์œจ์ ์ธ ํ† ํฐ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ Redis ๋„์ž…
  • ์ธ์ฆ์ด ํ•„์š”ํ•œ URL ๊ณตํ†ต ๊ด€๋ฆฌ
  • Spring Security ์ธ์ฆ ํ•„ํ„ฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ
yongh๐Ÿ™‚
yongh๐Ÿ™‚
yongh-dev ๋‹˜์˜ ๋ธ”๋กœ๊ทธ ์ž…๋‹ˆ๋‹ค.
  • yongh๐Ÿ™‚
    ๊ฐœ๋ฐœ ๊ธฐ๋ก
    yongh๐Ÿ™‚
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (9)
      • ํ”„๋กœ์ ํŠธ (9)
        • NolGoat (9)
  • ์ตœ๊ทผ ๊ธ€

  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.2
yongh๐Ÿ™‚
์ธ์ฆ ๋ณด์•ˆ ๊ฐ•ํ™”
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”