์น ์ ํ๋ฆฌ์ผ์ด์
์ด ์ ์ ๋ ๋ณต์กํด์ง๊ณ ๋์ ์ผ๋ก ๋ณํ๋ฉด์, ์ด๋ฅผ ๊ณต๊ฒฉํ๋ ๋ฐฉ์ ์ญ์ ๋ค์ํด์ง๊ณ ์์ต๋๋ค. ๊ทธ์ค์์๋ Cross-Site Scripting(XSS) ๊ณต๊ฒฉ์ ๊ฐ์ฅ ํํ๋ฉด์๋ ์ํํ ๋ณด์ ์ํ์ธ๋ฐ์, ์ด๋ฒ ํฌ์คํธ์์๋ XSS๊ฐ ๋ฌด์์ธ์ง, ์ด๋ป๊ฒ ์๋ํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํ ๋ํ์ ์ธ ๊ธฐ๋ฒ์ธ escapeHTML
ํจ์์ ์๋ฆฌ์ ๋ํด ์ดํด๋ณด๊ณ ์ ํฉ๋๋ค.
Cross-Site Scripting(XSS)
๋ ๊ณต๊ฒฉ์๊ฐ ์น ํ์ด์ง์ ์
์์ ์ธ ์คํฌ๋ฆฝํธ๋ฅผ ์ฝ์
ํ์ฌ, ํด๋น ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ์คํ๋๋๋ก ์ ๋ํ๋ ๊ณต๊ฒฉ ๋ฐฉ์์
๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ์ฌ์ฉ์๋ก๋ถํฐ ์
๋ ฅ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆ ์์ด ๊ทธ๋๋ก ์คํํ๋ ์ํฉ์ ์ด์ฉํ์ฌ, ๊ธฐ์กด ์๋์ ๋ค๋ฅธ HTML๊ณผ JavaScript ์ฝ๋๊ฐ ์คํ๋๊ฒ ๋ง๋๋ ๊ฑฐ์ฃ ๐
์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ์๋ก๋ถํฐ ํ ์คํธ ์ ๋ ฅ์ ๋ฐ๋ ํฌ๋ ๋ฆฌ์คํธ ๊ฐ์ ๊ฐ๋จํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์๋ XSS ๊ณต๊ฒฉ์ ์ํ์ ์กด์ฌํฉ๋๋ค. ์ฌ์ฉ์๊ฐ HTML ํ์์ ๋ฌธ์์ด์ ์ ๋ ฅํ ๋, ์ด ์ ๋ ฅ์ด ์ ๋๋ก ๊ฒ์ฆ๋์ง ์์ผ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ HTML ํ๊ทธ๋ก ํด์ํ์ฌ ํ์ด์ง์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๊พธ๊ฑฐ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์๊ฑฐ๋ ์๐จ
์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ <h2>Buy Groceries</h2>
๋ผ๋ ํ
์คํธ๋ฅผ ์
๋ ฅํ๋ค๊ณ ๊ฐ์ ํ์ ๋, ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฅผ ํ
์คํธ๊ฐ ์๋ HTML๋ก ํด์ํ์ฌ ํฌ๋ ํญ๋ชฉ์ ํฐ ์ ๋ชฉ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ตฌ์กฐ ๋ณํ๋ ๊ธฐ๋ฅ์ ์ผ๋ก๋ ํฐ ๋ฌธ์ ๊ฐ ์์ ์ ์์ง๋ง, ์ฌ์ ํ ์ฌ์ฉ์๊ฐ ์๋ํ ๋๋ก ํ์๋์ง ์๋ ๋น์ ์์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ๋ณ์ ์ ์์ต๋๋ค.
๋ฌผ๋ก ์ด ์ญ์ ํฌ๋ํฐ ์ค๋ฅ๊ธด ํ์ง๋ง, ์ ๋ง ๋ฌด์์ด ์ํ ์์๋ ์ฌ์ฉ์๊ฐ <script>
ํ๊ทธ์ ๊ฐ์ ์
์์ ์ธ JavaScript ์ฝ๋๋ฅผ ์
๋ ฅํ๋ ๊ฒ์
๋๋ค. ๋จ์ํ ์น ํ์ด์ง์ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ ๊ฒ์ ๋์ด์์ ๋ธ๋ผ์ฐ์ ์์ JavaScript๊ฐ ์คํ๋๊ฒ ํจ์ผ๋ก์จ ์ฌ์ฉ์ ์ธ์
์ ํ์ทจํ๊ฑฐ๋ ์
์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์์คํ
์ ๊ณต๊ฒฉํ ์ ์๋ ๊ฒ์ด์ฃ .
<script>alert('XSS Attack');</script>
์์ ๊ฐ์ ์ ์์ ์ธ ์ฝ๋๊ฐ ํฌ๋ ๋ฆฌ์คํธ์ ์ ๋ ฅ๋๋ค๊ณ ๊ฐ์ ํ๋ฉด, ๋ธ๋ผ์ฐ์ ๋ ์ด ์ฝ๋๋ฅผ ์คํํ๊ฒ ๋๊ณ , ์ฌ์ฉ์๋ ์๋ฆผ ์ฐฝ์ ํตํด ๊ณต๊ฒฉ์ด ์ฑ๊ณตํ๋ค๋ ์ฌ์ค์ ์๊ฒ ๋๋๊ฑฐ์ฃ . ์ค์ ๊ณต๊ฒฉ์์๋ ์ฌ์ฉ์์ ์ฟ ํค, ๋ก๊ทธ์ธ ์ ๋ณด ๋ฑ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ํ์น๊ฑฐ๋, ์ฌ์ฉ์์ ๊ณ์ ์ผ๋ก ์์น ์๋ ์์ ์ ์ํํ ์๋ ์์ต๋๋ค.
XSS๋ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ์ ์ ๋ ฅ์ ์ ์ฉํ์ฌ ์ ์ฑ ์ฝ๋๋ฅผ ์คํํ์ง๋ง, ์ด๋ค ์ทจ์ฝ์ ์ ์ด์ฉํ๋๋์ ๋ฐ๋ผ ์ ํ์ด ๋๋ฉ๋๋ค.
์ ์ฅํ XSS๋ ๊ณต๊ฒฉ์๊ฐ ์๋ฒ์ ์ ์์ ์ธ ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ฅํ๊ณ , ์ด๋ฅผ ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ์คํ๋๊ฒ ํ๋ ๋ฐฉ์์ ๋๋ค. ๋ณดํต์ ๊ฒ์๊ธ, ๋๊ธ, ํ๋กํ ์ ๋ณด ๊ฐ์ ์ฌ์ฉ์ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์์ฑํ ๋ด์ฉ์ด ์๋ฒ์ ์ ์ฅ๋๊ณ , ์ดํ ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ๋, ์๋ฒ๋ ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ๊ทธ๋๋ก ๋ฐํํ๊ฒ ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ๊ฒ์๊ธ์ <script>alert('XSS');</script>
๋ฅผ ์
๋ ฅํ๋ฉด, ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ๊ทธ ๊ฒ์๊ธ์ ๋ณผ ๋ ํด๋น ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ฉ๋๋ค.
๋ฐ์ฌํ XSS๋ ์ฌ์ฉ์์ ์์ฒญ์ ์ฆ์ ๋ฐ์ํ์ฌ ๋ฐ์ํ๋ ๋ฐฉ์์ ๋๋ค. ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ฐ์ดํฐ๊ฐ ์๋ฒ์ ์ ์ฅ๋์ง ์๊ณ , ์ฆ์ ๋ฐ์ฌ๋์ด ์น ํ์ด์ง์ ํ์๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก URL ๋งค๊ฐ๋ณ์๋ฅผ ์ด์ฉํ ๊ณต๊ฒฉ์ด ์์ฃผ ๋ฐ์ํฉ๋๋ค. ๊ณต๊ฒฉ์๊ฐ ์ ์์ ์ธ URL์ ์์ฑํ๊ณ , ์ด๋ฅผ ํด๋ฆญํ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์์ URL์์ ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, URL์ http://example.com/search?q=<script>alert('XSS');</script>
๋ฅผ ํฌํจํ๋ฉด, ์๋ฒ๋ ์ด ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋๋ก ์น ํ์ด์ง์ ๋ฐ์ํ๊ณ , ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค.
DOM ๊ธฐ๋ฐ XSS๋ ์๋ฒ ์ธก์์ ์ฒ๋ฆฌ๋์ง ์๊ณ ํด๋ผ์ด์ธํธ ์ธก์์ ๋ฐ์ํ๋ ๋ฐฉ์์ผ๋ก, ๋ธ๋ผ์ฐ์ ์ DOM์ ์ง์ ์กฐ์ํ์ฌ ์ ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ฒ ๋ง๋ญ๋๋ค. ๋ณดํต JavaScript์์ ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์์ ๋ฐ์ํ๋๋ฐ, HTML ์์๋ URL ํ๋ผ๋ฏธํฐ ๋ฑ์ JavaScript๋ก ์กฐ์ํ ๋ ๋ฐ์ํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, JavaScript ์ฝ๋์์ document.location.search
๊ฐ์ ์ง์ HTML์ ์ฝ์
ํ ๋, ๊ณต๊ฒฉ์๋ ์
์ฑ ์ฝ๋๋ฅผ URL ํ๋ผ๋ฏธํฐ์ ํฌํจ์์ผ ์คํํ ์ ์์ต๋๋ค.
์ด๋ฌํ XSS๋ฅผ ํตํด์ ์ฌ์ฉ์์ ์ธ์ ์ฟ ํค๋ฅผ ๊ฐ๋ก์ฑ์ด ์ฌ์ฉ์ ๊ณ์ ์ ๋ฌด๋จ์ผ๋ก ์ ๊ทผํ๋ ์ธ์ ํ์ด์ฌํน์ด๋, ๊ฐ์ง ๋ก๊ทธ์ธ ์ฌ์ดํธ๋ก ์ฌ์ฉ์๋ฅผ ์ ๋ํ๋ ๋ฑ์ ํผ์ฑ ๊ณต๊ฒฉ์ด ์ด๋ฃจ์ด์ง๋๋ค๐ฐ
์น ์ ํ๋ฆฌ์ผ์ด์
์์ XSS ๊ณต๊ฒฉ์ ๋ฐฉ์งํ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ์
๋ ฅ๋ฐ์ ๋ฐ์ดํฐ์์ <, >, &, ', "
์ ๊ฐ์ ํน์ ๋ฌธ์๋ฅผ HTML ํ๊ทธ๊ฐ ์๋ ๋จ์ํ ํ
์คํธ๋ก ์ธ์๋๊ฒ์ํฐํฐ ์ธ์ฝ๋ฉ
์ ํ๋ ๊ฒ์
๋๋ค. escapeHTML
ํจ์๋ ์ด๋ฌํ ์ํฐํฐ ์ธ์ฝ๋ฉ ๊ณผ์ ์ ํตํด ์ฌ์ฉ์๋ฅผ XSS ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํฉ๋๋ค.
export function escapeHTML(input) {
const div = document.createElement('div');
div.appendChild(document.createTextNode(input));
return div.innerHTML;
}
escapeHTML
ํจ์๋ ์ฌ์ฉ์๋ก๋ถํฐ ์
๋ ฅ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ HTML๋ก ํด์๋์ง ์๊ณ ํ
์คํธ๋ก ์ฒ๋ฆฌ๋๋๋ก ๋ณํํ๋ ๊ธฐ๋ฅ์ ์ํํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฅผ ์ด์ฉํ์ฌ HTML ํน์ ๋ฌธ์๋ฅผ ํน์ ์ํฐํฐ๋ก ๋ณํํจ์ผ๋ก์จ <, >, &
๋ฑ๊ณผ ๊ฐ์ ๋ฌธ์๊ฐ HTML ํ๊ทธ๋ก ์ธ์๋์ง ์๋๋ก ํฉ๋๋ค. ์ด๋ ๊ฒ ๋ณํ๋ ๋ฌธ์๋ ๊ทธ์ ํ๋ฉด์ ์ถ๋ ฅ๋ ๋ฟ, ์
์์ ์ธ HTML ํ๊ทธ๋ ์คํฌ๋ฆฝํธ๋ก ์คํ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ณด์์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
element.innerHTML = "<script>alert('XSS');</script>";
๋ง์ฝ innerHTML
์์ฑ์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์
๋ ฅ์ ์ง์ DOM์ ์ฝ์
ํ๋ฉด, ๋ธ๋ผ์ฐ์ ๋ ์
๋ ฅ๋ ๋ฌธ์์ด์ HTML๋ก ํด์ํ๊ณ ์คํํ๊ฒ ๋ฉ๋๋ค. ์ด๋ก ์ธํด <script>
ํ๊ทธ๊ฐ ๊ทธ๋๋ก ์คํ๋์ด, XSS ๊ณต๊ฒฉ์ ๋
ธ์ถ๋ ์ํ์ด ์กด์ฌํ๋ ๊ฒ์ด์ฃ .
ํ์ง๋ง ์ด์ ๋ฌ๋ฆฌ, escapeHTML
ํจ์๋ ๋ธ๋ผ์ฐ์ ์ DOM API๋ฅผ ํตํด ์
๋ ฅ๊ฐ์ HTML์ด ์๋ ํ
์คํธ ๋
ธ๋๋ก ์ฒ๋ฆฌ
ํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ํ
์คํธ ๋
ธ๋๋ฅผ ์์ฑํ ๋ HTML์ ์คํํ์ง ์๊ณ , ๋ชจ๋ ํน์ ๋ฌธ์๋ฅผ ์๋์ผ๋ก ์ํฐํฐ๋ก ๋ณํํ๊ธฐ์ ์ฌ์ฉ์๊ฐ <script>
์ ๊ฐ์ ์
์์ ์ธ ํ๊ทธ๋ฅผ ์
๋ ฅํด๋, ์ด๋ฅผ ๊ทธ์ ํ
์คํธ๋ก๋ง ์ทจ๊ธํ์ฌ ์คํ๋์ง ์๋ ์ํ๋ก ์ถ๋ ฅํ๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
์๊น ์์๋ฅผ ๋ค์๋ ์๋ ์ฝ๋๋,
<script>alert('XSS');</script>
escapeHTML
ํจ์์ ์ํด ๋ค์๊ณผ ๊ฐ์ ๋จ์ ํ
์คํธ๋ก ๋ณํ๋ฉ๋๋ค.
<script>alert('XSS');</script>
๋ธ๋ผ์ฐ์ ๋ <script>
ํ๊ทธ๋ฅผ HTML๋ก ํด์ํ์ง ์๊ณ , ํ
์คํธ๋ก๋ง ํ์ํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๊ณต๊ฒฉ์๊ฐ ์๋ํ JavaScript ์ฝ๋๊ฐ ์คํ๋์ง ์๊ณ , ํ๋ฉด์๋ ์์ ํ๊ฒ ๋ณํ๋ HTML ์ฝ๋๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
๋น๋ก escapeHTML
ํจ์๊ฐ XSS ๊ณต๊ฒฉ์ ๋ฐฉ์งํ๋ ๋ฐ ๋งค์ฐ ํจ๊ณผ์ ์ด์ง๋ง ๋ช๋ช ์ํฉ์์๋ ํ๊ณ๋ฅผ ์ง๋๋๋ค. ์ฐ์ , CSS ์ธ์ ์
์ด๋ URL ๊ธฐ๋ฐ ๊ณต๊ฒฉ
๋ฑ์ ์ ํ์ ์ฐจ๋จํ์ง ๋ชปํฉ๋๋ค. ์๋ฅผ ๋ค์ด, CSS์์ url() ํจ์์ ์
์์ ์ธ ๋ฐ์ดํฐ๋ฅผ ํฌํจ์ํฌ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ๊ณต๊ฒฉ์๋ ์ฌ์ฉ์๋ฅผ ํผ์ฑ ์ฌ์ดํธ๋ก ๋ฆฌ๋๋ ์
ํ๊ฑฐ๋, CSS ํ์ผ์ ์
์ฑ ์ฝ๋๋ฅผ ์ฌ์ ์ ์์ต๋๋ค. ๋ํ, DOM ๊ธฐ๋ฐ XSS ๊ณต๊ฒฉ
์ escapeHTML
ํจ์๋ก ํด๊ฒฐ๋์ง ์๋ ๊ฒฝ์ฐ๊ฐ ์กด์ฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด, JavaScript ์ฝ๋๊ฐ ์ง์ DOM์ ์กฐ์ํ๋ ์ํฉ์์๋ DOM ์์์ ์์ฑ์ด๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์
์ฑ ์ฝ๋๋ฅผ ์ฝ์
ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ํ๊ณ์ ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์, escapeHTML
ํจ์๋ XSS ๋ฐฉ์ง์ ์์ ํ ํด๊ฒฐ์ฑ
์ด ์๋๋ผ, ๋ณด์กฐ์ ์ธ ๋ณด์ ๋ ์ด์ด๋ก ์ดํดํด์ผ ํฉ๋๋ค. XSS์ ๊ฐ์ ๊ณต๊ฒฉ์ ์๋ฒฝํ ๋ฐฉ์งํ๊ธฐ ์ํด์๋ ๋ณด์ ํค๋๋ฅผ ์ค์ ํ๊ฑฐ๋, ์ฌ์ฉ์ ์
๋ ฅ์ ์ฒ ์ ํ๊ฒ ๊ฒ์ฆํ๊ณ ํํฐ๋งํ๋ ๋ฑ์ ๋ณด์ ์กฐ์น๊ฐ ํจ๊ป ์ด๋ฃจ์ด์ ธ์ผ ํฉ๋๋ค.
์ง๊ธ๊น์ง XSS์ ์ด๋ฅผ ํด๊ฒฐํ๋ ์ฒซ ๋ฒ์งธ ๋ฐฉ์ด์ ์ธ escapeHTML
ํจ์์ ๋ํด ์์๋ณด์์ต๋๋ค. escapeHTML
์ XSS ๋ฐฉ์ง์ ํจ๊ณผ์ ์ธ ๋๊ตฌ์ด์ง๋ง, CSS ์ธ์ ์
์ด๋ DOM ๊ธฐ๋ฐ XSS ๊ฐ์ ๋ค์ํ ์ํ์ ๋๋นํ๊ธฐ ์ํด์๋ ์ถ๊ฐ์ ์ธ ๋ณด์ ๋์ฑ
์ด ํ์ํฉ๋๋ค.
๊ฒฐ๊ตญ, ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด์์ ์ ์งํ๋ ค๋ฉด ํ ๊ฐ์ง์ ๊ธฐ๋ฒ์ ์์กดํ์ง ์๊ณ , ์ฌ๋ฌ ๋ณด์ ๊ณ์ธต์ ๊ฒฐํฉํ์ฌ ๋ณตํฉ์ ์ด๊ณ ๊ฐ๋ ฅํ ๋ฐฉ์ด์ฒด๊ณ๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๊ทธ๋ฌํ ๋ค์ธต์ ์ธ ์ ๊ทผ์ ํตํด ์ง์์ ์ผ๋ก ๋ณํํ๋ ๋ณด์ ์ํ์ ๋์ํ ์ ์์ ๊ฒ์ ๋๋ค.