์๋ ๋งํฌ๋ฅผ ํด๋ฆญํด ์๋ก์ด ๋ธ๋ก๊ทธ์์ ๋ ๋ง์ ๊ธ์ ๋ง๋๋ณด์ธ์.
๐
์ด์ ๋ธ๋ก๊ทธ ๋ฐ๋ก ๊ฐ๊ธฐ
[security] XSS ๊ณต๊ฒฉ

๐ XSS
XSS(Cross-Site Scripting)๋ ๊ณต๊ฒฉ์๊ฐ ์ ๋ขฐํ ์ ์๋ ์น์ฌ์ดํธ(์ ๋ช ํ ์ฌ์ดํธ ํน์ ๋ด๊ฐ ๋ง๋ ์ฌ์ดํธ)์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ์ ํ์ฌ ๋ค๋ฅธ ์ฌ์ฉ์ ๋ธ๋ผ์ฐ์ ์์ ์๋ ์ํค๋ ๊ณต๊ฒฉ
๐ XSS ๊ณต๊ฒฉ์ ์ข ๋ฅ
1. Stored XSS(์ ์ฅํ)
๋ํ์ ์ธ ์์๋ก ๊ฒ์ํ์ ๊ณต๊ฒฉ์๊ฐ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์ฌ ๊ฒ์ํ์ ์ ์ฅํ๊ณ ๊ทธ๊ฑธ ๋ค๋ฅธ ์ฌ์ฉ์๋ค์ด ๋ณด๋ ์๊ฐ ์๋์ํค๋ ๊ณต๊ฒฉ
๋ด๊ฐ ๊ฒ์ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๊ณ ๊ฒ์ํ์ ์ ์ฅํ๋ฉด ๋ค๋ฅธ ์ฌ์ฉ์๋ค์ด ๋ณด๋ ์๊ฐ ์๋์ผ๋ก โ๋น์ ์ ์ ๋ณด๊ฐ ํธ๋ ธ์ด์โ๊ฐ ์คํ๋จ.

2. Reflected XSS(๋ฐ์ฌํ)
url์ ๊ทธ๋๋ก ๋ณด์ฌ์ฃผ๋ ์ฌ์ดํธ๊ฐ ์๋ค๋ฉด ๊ณต๊ฒฉ์๊ฐ ์คํฌ๋ฆฝํธ๋ฅผ url์ ์ถ๊ฐํ์ฌ ๋ค๋ฅธ ์ฌ์ฉ์๋ค์ด ๋ณด๋ ์๊ฐ ์๋์ผ๋ก โ๋น์ ์ ์ ๋ณด๊ฐ ํธ๋ ธ์ด์โ๊ฐ ์คํ๋จ.
http://example.com/search?q=<script>alert(โ๋น์ ์ ์ ๋ณด๊ฐ ํธ๋ ธ์ด์โ)</script>
url์ฐฝ์ ๋ณด๋ฉด ๋ณํ๊ฑธ ์ ์ ์์.

3. DOM-based XSS(๋ ๊ธฐ๋ฐ)
DOM ๊ฐ์ฒด๋ฅผ ์ ์ดํ๋ ๊ณผ์ ์์ ์คํฌ๋ฆฝํธ๋ก ๊ณต๊ฒฉํ๋ ๋ฐฉ๋ฒ. url ์ดํ ํด์๊ฐ์ผ๋ก ๊ณต๊ฒฉํ๋ ์คํ์ผ์.

๐ ๋ฐ์ฌํ๊ณผ DOM-based์ ์ฐจ์ด
๋จผ๊ฐ ์ ์ฌํ๊ฒ ๋ณด์ธ๋ค. ํ์ง๋ง, ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ๋ ์์ ์ด ๋ค๋ฅด๋ค.
๋ฐ์ฌํ์ ์ผ๋จ ํ๋ฒ ์๋ฒ์ ์ ๋ฌ๋์ด์ผํจ.
๐ ๋ฐ์ฌํ ๊ณต๊ฒฉ ํ๋ฆ
- ์ฌ์ฉ์ ํด๋ฆญ - ์ ์ฑ ๋งํฌ ํด๋ฆญ
- ์๋ฒ ์ ๋ฌ - ์์ฒญ์ด ์๋ฒ๋ก ์ ์ก
- ๊ฒ์ฆ ์๋ต - ์๋ฒ์์ ์ ๋ ฅ๊ฐ ๊ฒ์ฆ ์์ด ์๋ต
- ์ ์ฑ ์ฝ๋ ์คํ - ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ต์ ์คํฌ๋ฆฝํธ๋ก ํด์ํ์ฌ ์คํ
DOM-based๋ ๋ณ๋์ ์๋ฒ ์์ฒญ์ด ์์.
๐ DOM-based ๊ณต๊ฒฉ ํ๋ฆ
- ์ฌ์ฉ์ ํด๋ฆญ - ์ ์ฑ ๋งํฌ ํด๋ฆญ
- ์ ์ HTML ์๋ต - ์๋ฒ์์ ์ ์์ ์ธ HTML ๋ฌธ์ ์๋ต
- ํด๋ผ์ด์ธํธ ์ธก ์ฒ๋ฆฌ - ๋ธ๋ผ์ฐ์ ๊ฐ JavaScript ์คํ
- URL ํ์ฑ - JavaScript๊ฐ URL์ ํด์(#) ๋ถ๋ถ์์ ์ ์ฑ ์คํฌ๋ฆฝํธ ์ถ์ถ
- DOM ์กฐ์ - ์ถ์ถํ ์คํฌ๋ฆฝํธ๋ก DOM ์กฐ์
- ์ ์ฑ ์ฝ๋ ์คํ - ์กฐ์๋ DOM์ ํตํด ์ ์ฑ ์คํฌ๋ฆฝํธ ์คํ
๐ฅ ๋์ฒ๋ฒ
XSS ๊ฐ์ ํด๋ผ์ด์ธํธ ์ธก ๋ณด์ ๋ฌธ์ ๋ ์ ๋ ฅ ๊ฒ์ฆ๊ณผ ์ถ๋ ฅ ์ด์ค์ผ์ดํ์ผ๋ก ํด๊ฒฐํ๋ค. ์ฌ์ฉ์ ์ ๋ ฅ์ ์๋ฒยทํด๋ผ์ด์ธํธ ์์ชฝ์์ ๊ฒ์ฆํ๊ณ , HTML๋ก ์ถ๋ ฅํ ๋๋ ํน์ ๋ฌธ์๋ฅผ ๋ฐ๋์ ์ด์ค์ผ์ดํ ์ฒ๋ฆฌํด์ผํ๋ค.
1. ์์ ํ ์ ๋ ฅ ๊ฒ์ฆ
innerHTML๋ก ๊ทธ๋๋ก ๋ฃ์ง ๋ง๊ณ ํ
์คํธ ์ ์ฉ API๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, HTML์ ํ์ฉํด์ผ ํ ๋๋ ๊ฒ์ฆ๋ sanitizer๋ฅผ ์ฌ์ฉ.
// โ ์๋ชป๋ ๋ฐฉ๋ฒ (์ทจ์ฝ)
element.innerHTML = userInput;
// โ
์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ (์๋ ์ด์ค์ผ์ดํ)
element.textContent = userInput;
// โ
HTML์ด ํ์ํ ๊ฒฝ์ฐ (๊ฒ์ฆ๋ sanitizer ์ฌ์ฉ)
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
ํนํ, ์ํํ DOM API๋ ์ฌ์ฉํ์ง ์๋๊ฒ ์ข๋ค.
// โ ์ํํ DOM API
innerHTML, insertAdjacentHTML, document.write, eval, new Function
2. Content-Security-Policy (CSP)
CSP๋ฅผ ๋์ ํ๋ฉด ๋ธ๋ผ์ฐ์ ์ฐจ์์์ ์คํ ๊ฐ๋ฅํ ์คํฌ๋ฆฝํธ ์์ค๋ฅผ ์ ํ ๊ฐ๋ฅ. ํค๋ ๋๋ ๋ฉํ ํ๊ทธ ๋ฐฉ์์ผ๋ก ์ ์ฉํ๋ฉด ๋๋ค.
<!-- ์: ๋ฉํ ํ๊ทธ ๋ฐฉ์ (์ค๋ฌด์์๋ HTTP ํค๋๋ก ์ค์ ๊ถ์ฅ) -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted-cdn.com;">
3. ์ธ์ ๋ณดํธ โ HttpOnly ์ฟ ํค
์ธ์ ์ฟ ํค์ HttpOnly(๋ฐ Secure, SameSite) ํ๋๊ทธ๋ฅผ ์ค์ ํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฟ ํค๋ฅผ ์ฝ์ง ๋ชปํ๊ฒ ํด ์ธ์ ํ์ทจ ์ํ์ ์ค์ด๋ฉด ๋จ.
Set-Cookie: sessionId=...; HttpOnly; Secure; SameSite=Strict
4. ํ๋ ์์ํฌ/ํ ํ๋ฆฟ ์ฌ์ฉ ๊ถ์ฅ
์ฌ๋์ ๋๊ตฌ๋ ์ค์ํ๋ค. ๊ทธ๋์ ์ด๋ฏธ ๋ง๋ค์ด์ง ํ๋ ์์ํฌ๋ ํ ํ๋ฆฟ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. react, vue, angular ๋ฑ ์ฃผ์ ํ๋ ์์ํฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ถ๋ ฅ ์ด์ค์ผ์ดํ๋ฅผ ์ ๊ณตํจ.
๋๊ธ๋จ๊ธฐ๊ธฐ