html-react-parser๋ฅผ ์ฌ์ฉํ์ฌ CMS์์ HTML์ ์ญ์ ํ๊ณ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ ์ถ์ต๋๋ค. XSS ๊ณต๊ฒฉ์์ ์ ๋ ฅ์ ํจ๊ณผ์ ์ผ๋ก ์ญ์ ํฉ๋๊น? https://stackoverflow.com/questions/29044518/safe-alternative-to-dangerouslysetinnerhtml#answer -48261046 ๊ทธ๋ ๊ฒ ์ฃผ์ฅํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด README์ ์ด๋๊ฐ์ ์ด๊ฒ์ ๋ฌธ์ํ/๊ด๊ณ ํ๋ ๊ฒ์ด ์ข์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์์ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
์ข์ ์ง๋ฌธ @dave-stevens-net!
๋ถํํ๋ ๊ทธ๋ ์ง ์์ต๋๋ค. ๊ทธ ์ด์ ๋ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ฒฉํ์ง ์๊ณ ์ ์ฐํ๊ฒ ๋ง๋ค๊ธฐ๋ก ์ ํํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ต์ฒด ์ต์ ์ด ์์ง๋ง ๊ฐ๋ฅํ ๋ชจ๋ ๊ณต๊ฒฉ์ ๋ํด ๊ฒ์ฌํ๋ ๊ฒ์ ๋๋ฌด ๋ง์ ์ ์์ต๋๋ค. ๋์ ์ํํ๊ฒ SetInnerHTML ๊ณผ ํจ๊ป XSS ์๋ํ์ด์ ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์์ ๋๋ง ํ. ๋น ๋ฅธ ์๋ต์ ๊ฐ์ฌํฉ๋๋ค.
๋น์ ์ ๋งค์ฐ ํ์ํฉ๋๋ค. ์ด๊ฒ์ด @dave-stevens-net ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ด๋ผ๋ฉด ๋ฌธ์ ๋ฅผ ์ข ๊ฒฐํ ์ ์์ต๋๊น?
@dave-stevens-net ๋๋ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ XSS์ ์์ ํ์ง ์๋ค๋ ๊ฒ์ ๋ํด ์ผ์ฐ์ด ๋ง์ ์๋ชปํ์ ์ ์์ต๋๋ค.
๋๋ ์๋ dangerouslySetInnerHTML
์ด ์ฌ๊ธฐ ์ ์์กดํ๊ธฐ ๋๋ฌธ์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ XSS-์์ ํ์ง ์๋ค๊ณ ์๊ฐํ์ต๋๋ค.
๊ทธ๋ฌ๋ XSS ์ทจ์ฝ์ ์ ์ฌํํ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ์์ ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ๋ด ๋ฐ์ด์ฌ๋ฆฐ์ ์ฐธ์กฐํ์ญ์์ค.
XSS ๊ณต๊ฒฉ์ ์ฌํํ๋ ๋ฐ ์ด์ด ์๋ค๋ฉด ์๋ ค์ฃผ์ญ์์ค.
๊ฐ๋จํ XSS ๊ณต๊ฒฉ์ ์ฌํํ๋ ๋ฐ ์ฑ๊ณตํ์ต๋๋ค. ๋ ์์ ์ ์์ต๋๋ค.
๋ด ๋ฐ์ด์ฌ๋ฆฐ์ ํ์ธํ์ญ์์ค.
https://www.in-secure.org/misc/xss/xss.html ์์ ์ฐพ์์ต๋๋ค.
Sanitize -html ํจํค์ง ์ข ์์ฑ์ ์ฌ์ฉํ์ฌ Sanitize ๊ตฌ์ฑ ์์๋ฅผ ์ฝ๋ฉํ์ต๋๋ค.
import React from 'react'
import sanitizeHtml from 'sanitize-html'
const Sanitize = ({ html }) => {
const clean = sanitizeHtml(html, {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img', 'span']),
allowedAttributes: {
...
},
})
return (
<span
className="sanitized-html"
dangerouslySetInnerHTML={{ __html: clean }}
/>
)
}
export default Sanitize
์ฌ์ฉ ์:
<Sanitize html={data.wordpressPage.title} />
@harveydf ์ข์ ๋ฐ๊ฒฌ! ๋ฐ์ด์ฌ๋ฆฐ์ ๋ง๋ค๊ณ ๊ณต์ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
README.md
๋ฅผ ์
๋ฐ์ดํธํ์ฌ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ XSS์ ์์ ํ์ง ์๋ค๋ ์ ์ ์ ์ํ๊ฒ ์ต๋๋ค.
๋์ฉ๋์ด๊ธฐ ๋๋ฌธ์ Sanitize-html์ ์ฌ์ฉํ๊ณ ์ถ์ง ์์์ต๋๋ค. ๋์ dompurify๋ฅผ ์ฌ์ฉํ๋๋ฐ 10๋ฐฐ ๋ ์๊ณ CSS๋ฅผ ์ ๊ฑฐํ์ง ์์ต๋๋ค.
import parse, { domToReact } from 'html-react-parser'
import DOMPurify from 'dompurify'
import React from 'react'
// export function replaceNode() {}
export default function html(html, opts = {}) {
return parse(DOMPurify.sanitize(html), {
...{
replace: replaceNode,
},
...opts,
})
}
html('<iframe src=javascript:alert("xss")></iframe>')
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋์ฉ๋์ด๊ธฐ ๋๋ฌธ์ Sanitize-html์ ์ฌ์ฉํ๊ณ ์ถ์ง ์์์ต๋๋ค. ๋์ dompurify๋ฅผ ์ฌ์ฉํ๋๋ฐ 10๋ฐฐ ๋ ์๊ณ CSS๋ฅผ ์ ๊ฑฐํ์ง ์์ต๋๋ค.
html('<iframe src=javascript:alert("xss")></iframe>')