secure coding

HTTPS / JWT / CSRF ๊ฐœ๋… ์ •๋ฆฌ

Digital Audio Player 2025. 3. 11. 11:17

๐Ÿ” HTTPS์˜ ์—ญํ• ๊ณผ ์ค‘์š”์„ฑ

1๏ธโƒฃ HTTPS๋ž€?

**HTTPS (HyperText Transfer Protocol Secure)**๋Š” HTTP + SSL/TLS๋ฅผ ๊ฒฐํ•ฉํ•œ ํ”„๋กœํ† ์ฝœ์ด๋‹ค.
์ฆ‰, HTTP ํ†ต์‹ ์„ ์•”ํ˜ธํ™”ํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

๐Ÿ’ก HTTP vs HTTPS

HTTPHTTPS

๋ณด์•ˆ ์ˆ˜์ค€ ์•”ํ˜ธํ™” ์—†์Œ (ํ‰๋ฌธ ํ†ต์‹ ) ์•”ํ˜ธํ™” (TLS/SSL ์ ์šฉ)
๋ฐ์ดํ„ฐ ๋ณดํ˜ธ ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ ํƒˆ์ทจ ๊ฐ€๋Šฅ ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™”๋กœ ๋ณดํ˜ธ
์‚ฌ์šฉ ์‚ฌ๋ก€ ์ผ๋ฐ˜ ์›น์‚ฌ์ดํŠธ (๋ณด์•ˆ ์ค‘์š”X) ๋กœ๊ทธ์ธ, ๊ฒฐ์ œ, ๊ฐœ์ธ์ •๋ณด ์ฒ˜๋ฆฌ ๋“ฑ
๋ธŒ๋ผ์šฐ์ € ํ‘œ์‹œ ๐Ÿ”ด "์•ˆ์ „ํ•˜์ง€ ์•Š์Œ" ๊ฒฝ๊ณ  ๐ŸŸข ์ž๋ฌผ์‡  ์•„์ด์ฝ˜ (๐Ÿ”’) ํ‘œ์‹œ

2๏ธโƒฃ HTTPS์˜ ์ฃผ์š” ์—ญํ• 

โœ… 1) ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” (Encryption) → ๋ฐ์ดํ„ฐ ํƒˆ์ทจ ๋ฐฉ์ง€
โœ… 2) ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ (Integrity) → ๋ฐ์ดํ„ฐ ๋ณ€์กฐ ๋ฐฉ์ง€
โœ… 3) ์„œ๋ฒ„ ์ธ์ฆ (Authentication) → ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„์™€ ํ†ต์‹  ๋ณด์žฅ


๐Ÿ“Œ 1. ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” (Encryption)

HTTPS๋Š” SSL/TLS ์•”ํ˜ธํ™”๋ฅผ ์ ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณดํ˜ธํ•œ๋‹ค.
์ฆ‰, ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์™€ ์„œ๋ฒ„๊ฐ€ ์•”ํ˜ธํ™”๋œ ์ƒํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์—, ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ’ก HTTP ํ†ต์‹  (์•”ํ˜ธํ™” X)

POST /login HTTP/1.1
Host: example.com
username=admin&password=1234
 

โŒ ๊ณต๊ฒฉ์ž๊ฐ€ ๋„คํŠธ์›Œํฌ์—์„œ ํŒจํ‚ท์„ ๊ฐ€๋กœ์ฑ„๋ฉด ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ๋จ.

๐Ÿ’ก HTTPS ํ†ต์‹  (์•”ํ˜ธํ™” O)

POST /login HTTP/1.1
Host: example.com
[์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ]
 

โœ… ๊ณต๊ฒฉ์ž๊ฐ€ ํŒจํ‚ท์„ ๊ฐ€๋กœ์ฑ„๋”๋ผ๋„ ๋‚ด์šฉ์„ ํ•ด๋…ํ•  ์ˆ˜ ์—†์Œ.

๐Ÿ”น ์•”ํ˜ธํ™” ๋ฐฉ์‹

  • HTTPS๋Š” TLS(Transport Layer Security) ๋˜๋Š” **SSL(Secure Sockets Layer)**์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•œ๋‹ค.
  • ์‚ฌ์šฉ๋˜๋Š” ์•”ํ˜ธํ™” ๋ฐฉ์‹:
    • ๋Œ€์นญํ‚ค ์•”ํ˜ธํ™”: AES, ChaCha20 (๋น ๋ฅด๊ณ  ๊ฐ•๋ ฅํ•œ ์•”ํ˜ธํ™”)
    • ๋น„๋Œ€์นญํ‚ค ์•”ํ˜ธํ™”: RSA, ECC (๊ณต๊ฐœํ‚ค-๊ฐœ์ธํ‚ค ์‚ฌ์šฉ)

๐Ÿ“Œ 2. ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ (Integrity)

HTTPS๋Š” ๋ฐ์ดํ„ฐ ๋ณ€์กฐ๋ฅผ ๋ฐฉ์ง€ํ•œ๋‹ค.
์ฆ‰, ์ „์†ก ์ค‘์— ๊ณต๊ฒฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ณดํ˜ธํ•œ๋‹ค.

๐Ÿ”น HTTP์—์„œ๋Š” ๊ณต๊ฒฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€์กฐํ•  ์ˆ˜ ์žˆ์Œ

GET /profile HTTP/1.1
Host: example.com
 

๐Ÿ”ฅ ๊ณต๊ฒฉ์ž๊ฐ€ ์ค‘๊ฐ„์—์„œ ์‘๋‹ต์„ ๋ณ€์กฐํ•˜์—ฌ ์•…์„ฑ ์ฝ”๋“œ ์ถ”๊ฐ€:

HTTP/1.1 200 OK
Content-Type: text/html

<html>
  <script>alert('Hacked!')</script>
</html>
 

→ ๊ฒฐ๊ณผ: ์‚ฌ์šฉ์ž๊ฐ€ ์•…์„ฑ ์ฝ”๋“œ๊ฐ€ ์‚ฝ์ž…๋œ ํŽ˜์ด์ง€๋ฅผ ๋ณด๊ฒŒ ๋จ.

๐Ÿ”น HTTPS์—์„œ๋Š” ๋ฐ์ดํ„ฐ ๋ณ€์กฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ

  • TLS๋Š” **๋ฉ”์‹œ์ง€ ์ธ์ฆ ์ฝ”๋“œ(MAC, Message Authentication Code)**๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•จ.
  • ์ฆ‰, ๊ณต๊ฒฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€์กฐํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์—ฐ๊ฒฐ์„ ์ฐจ๋‹จํ•จ.

๐Ÿ“Œ 3. ์„œ๋ฒ„ ์ธ์ฆ (Authentication)

HTTPS๋Š” ํด๋ผ์ด์–ธํŠธ(์‚ฌ์šฉ์ž)๊ฐ€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„์— ์—ฐ๊ฒฐ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
์ฆ‰, ํ”ผ์‹ฑ ์‚ฌ์ดํŠธ(๊ฐ€์งœ ์‚ฌ์ดํŠธ)๋กœ ์œ ๋„๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“ ํ”ผ์‹ฑ ๊ณต๊ฒฉ ์˜ˆ์‹œ (HTTP)

  1. ์‚ฌ์šฉ์ž๊ฐ€ http://bank.example.com์— ์ ‘์†ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•จ.
  2. ๊ณต๊ฒฉ์ž๊ฐ€ DNS๋ฅผ ๋ณ€์กฐํ•˜์—ฌ http://fake-bank.com์œผ๋กœ ์œ ๋„ํ•จ.
  3. ์‚ฌ์šฉ์ž๋Š” ๊ฐ€์งœ ์€ํ–‰ ์‚ฌ์ดํŠธ์— ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ๊ณต๊ฒฉ์ž๋Š” ์ด๋ฅผ ํƒˆ์ทจํ•จ.

๐Ÿ“ HTTPS ์‚ฌ์šฉ ์‹œ ๋ฐฉ์–ด

  • HTTPS๋Š” ์„œ๋ฒ„๊ฐ€ ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋„๋ฉ”์ธ์ธ์ง€ ๊ฒ€์ฆํ•œ๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €๋Š” ์ธ์ฆ์„œ๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ฐ€์งœ ์‚ฌ์ดํŠธ๋ผ๋ฉด "์œ„ํ—˜" ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.

๐Ÿ’ก ๋ธŒ๋ผ์šฐ์ €์—์„œ HTTPS ์ธ์ฆ ํ™•์ธ

  1. ์ฃผ์†Œ์ฐฝ ์ž๋ฌผ์‡  ์•„์ด์ฝ˜ ๐Ÿ”’ ํด๋ฆญ
  2. "๋ณด์•ˆ ์—ฐ๊ฒฐ" ๋˜๋Š” "์ด ์›น์‚ฌ์ดํŠธ๋Š” ์ธ์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค" ํ‘œ์‹œ ํ™•์ธ
  3. ์ธ์ฆ์„œ ๋ฐœ๊ธ‰ ๊ธฐ๊ด€(CA) ํ™•์ธ (์˜ˆ: DigiCert, Let's Encrypt)

๐Ÿ“Œ 4. HTTPS๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

๐Ÿš€ HTTPS๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ ๋ฌธ์ œ 1๏ธโƒฃ ํŒจํ‚ท ์Šค๋‹ˆํ•‘(Packet Sniffing) → ๋กœ๊ทธ์ธ ์ •๋ณด, ์‹ ์šฉ์นด๋“œ ์ •๋ณด ํƒˆ์ทจ ๊ฐ€๋Šฅ
2๏ธโƒฃ MITM(Man-In-The-Middle) ๊ณต๊ฒฉ → ์ค‘๊ฐ„์—์„œ ๋ฐ์ดํ„ฐ ๋ณ€์กฐ ๊ฐ€๋Šฅ
3๏ธโƒฃ ํ”ผ์‹ฑ(Phishing) ๊ณต๊ฒฉ → ๊ฐ€์งœ ์‚ฌ์ดํŠธ๋กœ ์œ ๋„ ๊ฐ€๋Šฅ

๐Ÿ’ก ํŠนํžˆ JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ์—์„œ๋Š” HTTPS๊ฐ€ ํ•„์ˆ˜!

  • JWT๊ฐ€ ํ—ค๋”์— ํฌํ•จ๋˜์–ด ์ „์†ก๋˜๋ฏ€๋กœ, HTTPS๊ฐ€ ์—†์œผ๋ฉด ํ† ํฐ์ด ํƒˆ์ทจ๋  ์œ„ํ—˜์ด ํผ.
  • HTTP๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๊ณต๊ฒฉ์ž๊ฐ€ ๋„คํŠธ์›Œํฌ์—์„œ ํŒจํ‚ท์„ ๊ฐ€๋กœ์ฑ„ JWT๋ฅผ ํ›”์น  ์ˆ˜ ์žˆ์Œ.
  • HTTPS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด JWT๊ฐ€ ์•”ํ˜ธํ™”๋˜์–ด ๊ณต๊ฒฉ์ž๊ฐ€ ํƒˆ์ทจํ•ด๋„ ๋‚ด์šฉ์„ ์•Œ ์ˆ˜ ์—†์Œ.

๐Ÿ“Œ 5. ๊ฒฐ๋ก 

๐Ÿ”น HTTPS์˜ ์—ญํ•  ์š”์•ฝ

โœ” ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” → ๋„คํŠธ์›Œํฌ์—์„œ ํŒจํ‚ท์„ ๊ฐ€๋กœ์ฑ„๋„ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์—†์Œ.
โœ” ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ → ์ „์†ก ์ค‘์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€์กฐ๋˜์ง€ ์•Š์Œ.
โœ” ์„œ๋ฒ„ ์ธ์ฆ → ์‚ฌ์šฉ์ž๊ฐ€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„์— ์ ‘์†ํ•˜๋„๋ก ๋ณด์žฅ.

๐Ÿ”น HTTPS๋ฅผ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

โœ… ๋กœ๊ทธ์ธ ์‹œ์Šคํ…œ (JWT ์ธ์ฆ, OAuth 2.0 ๋“ฑ)
โœ… ์‹ ์šฉ์นด๋“œ ๊ฒฐ์ œ, ๊ฐœ์ธ์ •๋ณด ์ž…๋ ฅ์ด ํ•„์š”ํ•œ ์‚ฌ์ดํŠธ
โœ… API ํ†ต์‹  (ํ”„๋ก ํŠธ์—”๋“œ ↔ ๋ฐฑ์—”๋“œ)


๐Ÿ“Œ 6. ์ถ”๊ฐ€ ์งˆ๋ฌธ: "HTTPS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์™„๋ฒฝํ•œ ๋ณด์•ˆ์ธ๊ฐ€?"

โŒ ์•„๋‹ˆ๋‹ค. HTTPS๋Š” ๋ฐ์ดํ„ฐ ์ „์†ก ๊ตฌ๊ฐ„์„ ๋ณดํ˜ธํ•  ๋ฟ, ์„œ๋ฒ„ ๋‚ด๋ถ€ ๋ณด์•ˆ๊นŒ์ง€ ์ฑ…์ž„์ง€์ง€๋Š” ์•Š๋Š”๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด:

  • XSS(Cross-Site Scripting) ๊ณต๊ฒฉ → ์›น์‚ฌ์ดํŠธ์— ์•…์„ฑ JavaScript๊ฐ€ ์‚ฝ์ž…๋  ์ˆ˜๋„ ์žˆ์Œ.
  • SQL Injection → ์„œ๋ฒ„์˜ DB๊ฐ€ ์•ˆ์ „ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ์Œ.

๐Ÿš€ ๋”ฐ๋ผ์„œ, HTTPS ์™ธ์—๋„ ๋ณด์•ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค.

  • JWT๋ฅผ HttpOnly ์ฟ ํ‚ค์— ์ €์žฅ (XSS ๋ฐฉ์ง€)
  • JWT ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์งง๊ฒŒ ์„ค์ •
  • ๊ฐ•๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‹ฑ ์‚ฌ์šฉ (BCrypt ๋“ฑ)
  • SQL Injection ๋ฐฉ์–ด (Prepared Statement ์‚ฌ์šฉ)

โœ… ๊ฒฐ๋ก : HTTPS๋Š” ํ•„์ˆ˜๋‹ค!

1๏ธโƒฃ HTTP๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํ‰๋ฌธ์œผ๋กœ ์ „์†ก๋˜๋ฏ€๋กœ ๋งค์šฐ ์œ„ํ—˜
2๏ธโƒฃ HTTPS๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•˜์—ฌ ํƒˆ์ทจ ๋ฐ ๋ณ€์กฐ๋ฅผ ๋ฐฉ์ง€
3๏ธโƒฃ JWT ๊ฐ™์€ ํ† ํฐ ์ธ์ฆ ๋ฐฉ์‹์—์„œ๋Š” HTTPS ์—†์ด๋Š” ๋ณด์•ˆ์ด ์ทจ์•ฝ
4๏ธโƒฃ HTTPS๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„, ์ถ”๊ฐ€์ ์ธ ๋ณด์•ˆ ์กฐ์น˜๊ฐ€ ํ•„์š”

์ฆ‰, JWT, ๋กœ๊ทธ์ธ, ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ๋ฅผ ์œ„ํ•ด HTTPS๋Š” ์„ ํƒ์ด ์•„๋‹ˆ๋ผ ํ•„์ˆ˜๋‹ค! ๐Ÿš€

 

 

 

 

 

-------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- ------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------- -------------

 

๐Ÿ” CSRF๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ–ˆ๋Š”๋ฐ, JWT๋Š” ์•ˆ์ „ํ•œ๊ฐ€?

CSRF(Cross-Site Request Forgery) ๋ณดํ˜ธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ–ˆ๋Š”๋ฐ JWT๋Š” ์•ˆ์ „ํ•œ๊ฐ€? ํ•˜๋Š” ์งˆ๋ฌธ์ด ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜๋ฉด, CSRF์™€ JWT๋Š” ๋ณด์•ˆ ๋ชฉ์ ์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, JWT๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ CSRF ๋ณดํ˜ธ๊ฐ€ ํ•„์š” ์—†๋‹ค.
ํ•˜์ง€๋งŒ, JWT๊ฐ€ ํƒˆ์ทจ๋˜์—ˆ์„ ๋•Œ์˜ ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ๋ณ„๊ฐœ๋กœ ์กด์žฌํ•˜๋ฉฐ, ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์กฐ์น˜๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค.


๐Ÿ“Œ 1. CSRF๊ฐ€ ํ•˜๋Š” ์—ญํ• 

CSRF๋Š” ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์„ ์•…์šฉํ•˜์—ฌ ์•…์˜์ ์ธ ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋Š” ๊ณต๊ฒฉ์„ ๋ง‰๊ธฐ ์œ„ํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ์ด๋‹ค.

๐Ÿ’ก CSRF ๊ณต๊ฒฉ ์˜ˆ์‹œ
1๏ธโƒฃ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์˜ ์„ธ์…˜ ์ฟ ํ‚ค์— ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ์ €์žฅ๋จ
2๏ธโƒฃ ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต๊ฒฉ์ž๊ฐ€ ๋งŒ๋“  ์•…์„ฑ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•จ
3๏ธโƒฃ ์•…์„ฑ ์‚ฌ์ดํŠธ์—์„œ fetch("https://example.com/user/delete", { method: "POST" }) ๊ฐ™์€ ์š”์ฒญ์„ ์‹คํ–‰
4๏ธโƒฃ ๋ธŒ๋ผ์šฐ์ €๋Š” ์ž๋™์œผ๋กœ ์„ธ์…˜ ์ฟ ํ‚ค๋ฅผ ํฌํ•จํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋ƒ„ → ์‚ฌ์šฉ์ž๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ ๋ฐ์ดํ„ฐ ์‚ญ์ œ๋จ

โœ… CSRF ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์„ ๋•Œ, ์ด ์š”์ฒญ์ด ์ง„์งœ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ“Œ 2. JWT ์‚ฌ์šฉ ์‹œ CSRF๊ฐ€ ํ•„์š” ์—†๋Š” ์ด์œ 

โœ… JWT๋Š” ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ง์ ‘ HTTP ํ—ค๋”์— ํ† ํฐ์„ ํฌํ•จํ•˜์—ฌ ๋ณด๋ƒ„.
โœ… ๋”ฐ๋ผ์„œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ JWT๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์Œ → CSRF ๊ณต๊ฒฉ์ด ๋ถˆ๊ฐ€๋Šฅ.
โœ… ์ฆ‰, JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” CSRF ๋ณดํ˜ธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.

๐Ÿ’ก CSRF ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ ์ฟ ํ‚ค๋ฅผ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ,
JWT๋Š” ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ๋˜๋Š” ์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ ํ›„, ์ง์ ‘ Authorization ํ—ค๋”์— ํฌํ•จํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฏ€๋กœ CSRF ๊ณต๊ฒฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

GET /user/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
 
 

→ CSRF ๊ณต๊ฒฉ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ ์„ธ์…˜ ์ฟ ํ‚ค๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฐฉ์‹์—์„œ ๋ฐœ์ƒํ•˜๋Š”๋ฐ, JWT๋Š” ์ˆ˜๋™์œผ๋กœ ํ—ค๋”์— ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ ํ•ด๋‹น๋˜์ง€ ์•Š๋Š”๋‹ค.


๐Ÿ“Œ 3. JWT๊ฐ€ ํƒˆ์ทจ๋˜๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋Š”๊ฐ€?

JWT๋Š” ํ—ค๋”์—์„œ ํƒˆ์ทจ๋  ๊ฒฝ์šฐ ๊ณต๊ฒฉ์ž๊ฐ€ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ์กด์žฌํ•œ๋‹ค.
์ด๋Š” CSRF ๋ฌธ์ œ์™€๋Š” ๋ณ„๊ฐœ์ด๋ฉฐ, ํ† ํฐ ํƒˆ์ทจ(TOKEN THEFT) ๋ฌธ์ œ์— ํ•ด๋‹นํ•œ๋‹ค.

๐Ÿšจ ๊ณต๊ฒฉ์ž๊ฐ€ JWT๋ฅผ ํƒˆ์ทจํ•˜๋Š” ๋ฐฉ๋ฒ• 1๏ธโƒฃ Man-in-the-Middle (MITM) ๊ณต๊ฒฉ

  • HTTPS๊ฐ€ ์•„๋‹Œ HTTP๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๋„คํŠธ์›Œํฌ์—์„œ JWT๊ฐ€ ํƒˆ์ทจ๋  ์ˆ˜ ์žˆ๋‹ค.
    2๏ธโƒฃ XSS (Cross-Site Scripting) ๊ณต๊ฒฉ
  • JWT๋ฅผ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•  ๊ฒฝ์šฐ, XSS ์ทจ์•ฝ์ ์ด ์žˆ๋Š” ์‚ฌ์ดํŠธ์—์„œ ๊ณต๊ฒฉ์ž๊ฐ€ JavaScript๋ฅผ ์‹คํ–‰ํ•ด ํ† ํฐ์„ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ๋‹ค.
    3๏ธโƒฃ ํ† ํฐ์„ ๋„ˆ๋ฌด ์˜ค๋ž˜ ์œ ์ง€ํ•  ๊ฒฝ์šฐ
  • JWT๊ฐ€ ํƒˆ์ทจ๋˜๋ฉด ์„ธ์…˜์ฒ˜๋Ÿผ ๋ฌดํšจํ™”ํ•  ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋งŒ๋ฃŒ ์‹œ๊ฐ„์ด ๊ธธ ๊ฒฝ์šฐ ์œ„ํ—˜ํ•˜๋‹ค.

๐Ÿ“Œ 4. JWT ํƒˆ์ทจ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•

โœ… 1) HTTPS ์‚ฌ์šฉ (ํ•„์ˆ˜)

JWT๋Š” ํ—ค๋”์— ํฌํ•จํ•˜์—ฌ ์ „์†ก๋˜๋ฏ€๋กœ, ๋„คํŠธ์›Œํฌ์—์„œ ํƒˆ์ทจ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ HTTPS๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
            .requiresChannel(channel -> channel.anyRequest().requiresSecure()) // ๋ชจ๋“  ์š”์ฒญ์„ HTTPS๋กœ ๊ฐ•์ œ
            .build();
}
 

๐Ÿšจ HTTP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ JWT๋ฅผ ํƒˆ์ทจํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋งค์šฐ ๋†’์•„์ง„๋‹ค.


โœ… 2) JWT๋ฅผ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ๋Œ€์‹  HttpOnly ์ฟ ํ‚ค์— ์ €์žฅ

XSS ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, JWT๋ฅผ localStorage๊ฐ€ ์•„๋‹Œ HttpOnly ์ฟ ํ‚ค์— ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

Set-Cookie: token=eyJhbGciOiJIUzI1Ni...; HttpOnly; Secure
  • HttpOnly → JavaScript๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ (XSS ๋ฐฉ์–ด)
  • Secure → HTTPS์—์„œ๋งŒ ์ „์†ก

๐Ÿš€ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด XSS ๊ณต๊ฒฉ์œผ๋กœ JavaScript๊ฐ€ JWT๋ฅผ ์ฝ์–ด๊ฐ€์ง€ ๋ชปํ•จ.


โœ… 3) ์งง์€ JWT ๋งŒ๋ฃŒ ์‹œ๊ฐ„ + Refresh Token ์‚ฌ์šฉ

JWT๊ฐ€ ํƒˆ์ทจ๋  ๊ฒฝ์šฐ, ๋ฌดํšจํ™”ํ•  ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์งง๊ฒŒ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

private static final long JWT_EXPIRATION = 1000 * 60 * 15; // 15๋ถ„
  • ์งง์€ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ (15๋ถ„ ์ดํ•˜) → ํ† ํฐ์ด ํƒˆ์ทจ๋˜๋”๋ผ๋„ ์˜ค๋ž˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
  • Refresh Token ์‚ฌ์šฉ → ๋งŒ๋ฃŒ๋˜๋ฉด ์žฌ๋ฐœ๊ธ‰

โœ… 4) ๋กœ๊ทธ์•„์›ƒ ์‹œ ์„œ๋ฒ„์—์„œ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ๊ด€๋ฆฌ

JWT๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ์ด ์—†์Œ, ํ•˜์ง€๋งŒ ์„œ๋ฒ„์—์„œ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค.

Set<String> tokenBlacklist = new HashSet<>();

public void logout(String token) {
    tokenBlacklist.add(token);
}
public boolean isTokenBlacklisted(String token) {
    return tokenBlacklist.contains(token);
}
 

→ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์•„์›ƒํ•˜๋ฉด ํ•ด๋‹น JWT๋ฅผ ์„œ๋ฒ„์—์„œ ๋ฌดํšจํ™”ํ•˜์—ฌ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋„๋ก ํ•จ.


๐Ÿ“Œ 5. ๊ฒฐ๋ก 

Q. CSRF ๋ณดํ˜ธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ–ˆ๋Š”๋ฐ ๋ณด์•ˆ ๋ฌธ์ œ๋Š” ์—†๋Š”๊ฐ€?
JWT๋Š” ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ ์ธ์ฆ์ด ์•„๋‹ˆ๋ผ CSRF ๊ณต๊ฒฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— CSRF ๋ณดํ˜ธ๊ฐ€ ํ•„์š” ์—†๋‹ค.

Q. ํ•˜์ง€๋งŒ JWT๋ฅผ ํ—ค๋”์—์„œ ํƒˆ์ทจํ•  ๊ฐ€๋Šฅ์„ฑ์€ ์—†๋Š”๊ฐ€?
→ ๋งž๋‹ค. JWT ํƒˆ์ทจ(TOKEN THEFT)๋Š” ๋‹ค๋ฅธ ๋ณด์•ˆ ๋ฌธ์ œ์ด๋ฉฐ, ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด HTTPS, HttpOnly ์ฟ ํ‚ค, ์งง์€ ๋งŒ๋ฃŒ ์‹œ๊ฐ„, Refresh Token ๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.


๐Ÿš€ ๊ฒฐ๋ก : CSRF๋Š” ๋น„ํ™œ์„ฑํ™”ํ•ด๋„ ๋˜์ง€๋งŒ, JWT ํƒˆ์ทจ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ์ถ”๊ฐ€ ์กฐ์น˜๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค.

โœ… CSRF ๊ณต๊ฒฉ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„ธ์…˜ ์ฟ ํ‚ค๋ฅผ ์ž๋™์œผ๋กœ ํฌํ•จํ•˜๋Š” ๋ฐฉ์‹์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ → JWT๋Š” ํ•ด๋‹น๋˜์ง€ ์•Š์Œ
โœ… ํ•˜์ง€๋งŒ JWT๊ฐ€ ํƒˆ์ทจ๋  ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ถ”๊ฐ€์ ์ธ ๋ณด์•ˆ ์กฐ์น˜๊ฐ€ ํ•„์š”
โœ… HTTPS, HttpOnly ์ฟ ํ‚ค, ์งง์€ ๋งŒ๋ฃŒ ์‹œ๊ฐ„, Refresh Token ๋“ฑ์„ ํ™œ์šฉํ•ด์•ผ ํ•จ

์ฆ‰, JWT๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๋ฉด CSRF๊ฐ€ ์•„๋‹ˆ๋ผ "ํ† ํฐ ํƒˆ์ทจ"์— ๋Œ€ํ•œ ๋Œ€๋น„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค! ๐Ÿš€