
Sanitize는 허용 목록(allowlist) 기반의 HTML 및 CSS 새니타이저입니다. 허용하기로 선택한 요소, 속성, 프로퍼티를 제외한 모든 HTML 및/또는 CSS를 문자열에서 제거합니다.
간단한 구성 문법을 사용하여 Sanitize가 특정 HTML 요소, 해당 요소 내의 특정 속성, 그리고 URL을 포함하는 속성 내의 특정 URL 프로토콜을 허용하도록 지정할 수 있습니다. 또한 CSS를 포함하는 요소나 속성에서 특정 CSS 프로퍼티, @ 규칙, URL 프로토콜을 허용할 수도 있습니다. 명시적으로 허용하지 않은 HTML 또는 CSS는 모두 제거됩니다.
Sanitize는 현대 브라우저와 동일한 방식으로 HTML을 파싱하는 Nokogiri HTML5 파서와, 현대 브라우저와 동일한 방식으로 CSS를 파싱하는 Crass를 기반으로 합니다. 허용 목록 구성이 안전한 마크업과 CSS만 허용하는 한, 가장 잘못된 형식이거나 악의적인 입력이라도 안전한 출력으로 변환됩니다.
[!WARNING]
Sanitize는
<math>또는<svg>요소의 내용을 완전히 새니타이즈할 수 없습니다. MathML 및 SVG 요소는 일반적인 HTML 파싱 규칙을 따르지 않는 외래 요소(foreign elements)입니다.기본적으로 Sanitize는 모든 MathML 및 SVG 요소를 제거합니다. 사용자 정의 요소 허용 목록에 MathML 또는 SVG 요소를 추가하면 애플리케이션에 보안 취약점이 생길 수 있습니다.
gem install sanitize
require 'sanitize'
# Clean up an HTML fragment using Sanitize's permissive but safe Relaxed config.
# This also sanitizes any CSS in `<style>` elements or `style` attributes.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# Clean up an HTML document using the Relaxed config.
Sanitize.document(html, Sanitize::Config::RELAXED)
# Clean up a standalone CSS stylesheet using the Relaxed config.
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# Clean up some CSS properties using the Relaxed config.
Sanitize::CSS.properties(css, Sanitize::Config::RELAXED)
Sanitize는 다음과 같은 유형의 입력을 정화할 수 있습니다:
<style> 요소 내부의 CSS 스타일시트style 속성 내부의 CSS 속성[!WARNING]
Sanitize는
<math>또는<svg>요소의 내용을 완전히 정화할 수 없습니다. MathML 및 SVG 요소는 일반적인 HTML 파싱 규칙을 따르지 않는 외래 요소입니다.기본적으로 Sanitize는 모든 MathML 및 SVG 요소를 제거합니다. 사용자 정의 요소 허용 목록에 MathML 또는 SVG 요소를 추가하면 애플리케이션에 보안 취약점이 생길 수 있습니다.
프래그먼트는 루트 수준의 <html> 요소를 포함하지 않는 HTML 스니펫입니다.
구성 옵션을 지정하지 않으면 Sanitize는 기본적으로 가장 엄격한 설정을 사용하므로, 모든 HTML을 제거하고 안전한 텍스트만 남깁니다.
html = '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
Sanitize.fragment(html)
# => "foo"
특정 요소를 유지하려면 해당 요소를 요소 허용 목록에 추가하세요.
Sanitize.fragment(html, elements: ['b'])
# => "<b>foo</b>"
문서를 정리할 때 <html> 요소는 허용 목록에 포함되어야 합니다. 또한 :allow_doctype을 true로 설정하여 올바른 형식의 문서 유형 정의를 허용할 수 있습니다.
html = %[
<!DOCTYPE html>
<html>
<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">
</html>
]
Sanitize.document(html,
allow_doctype: true,
elements: ['html']
)
# => "<!DOCTYPE html><html>foo\n \n</html>"
HTML 프래그먼트나 문서에서 CSS를 정화하려면 먼저 <style> 요소 및/또는 style 속성을 허용 목록에 추가하세요. 그런 다음 허용하려는 CSS 속성, @ 규칙, URL 프로토콜을 허용 목록에 추가하세요. CSS 주석이나 브라우저 호환성 핵을 허용할지 여부도 선택할 수 있습니다.
html = %[
<style>
div { color: green; width: 1024px; }
</style>
<div style="height: 100px; width: 100px;"></div>
<p>hello!</p>
]
Sanitize.fragment(html,
elements: ['div', 'style'],
attributes: {'div' => ['style']},
css: {
properties: ['width']
}
)
#=> %[
# <style>
# div { width: 1024px; }
# </style>
#
# <div style=" width: 100px;"></div>
# hello!
# ]
Sanitize는 HTML 파서를 호출할 필요 없이 독립형 CSS 스타일시트나 속성 문자열을 문제없이 정리합니다.
[!WARNING] 이는 독립형 CSS 파일에서 사용할 CSS를 정리하는 용도로만 사용해야 합니다.
<style>요소나style속성과 같은 HTML 컨텍스트에서 사용할 CSS를 안전하게 정리하려면, 앞선 섹션에서 설명한 대로 적절한 허용 목록과 함께Sanitize.document()또는Sanitize.fragment()를 사용해야 합니다. 그렇게 하지 않으면 HTML 삽입 공격이 가능해질 수 있습니다.
css = %[
@import url(evil.css);
a { text-decoration: none; }
a:hover {
left: expression(alert('xss!'));
text-decoration: underline;
}
]
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# => %[
#
#
# a { text-decoration: none; }
#
# a:hover {
#
# text-decoration: underline;
# }
# ]
Sanitize::CSS.properties(%[
left: expression(alert('xss!'));
text-decoration: underline;
], Sanitize::Config::RELAXED)
# => %[
#
# text-decoration: underline;
# ]
울트라 세이프 기본 설정 외에도 Sanitize는 즉시 사용하거나 필요에 맞게 조정할 수 있는 세 가지 기본 제공 구성을 제공합니다.
매우 단순한 인라인 마크업만 허용합니다. 링크, 이미지, 블록 요소는 허용되지 않습니다.
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
# => "<b>foo</b>"
서식 요소, 링크, 목록을 포함한 다양한 마크업을 허용합니다.
이미지와 표는 허용되지 않으며, 링크는 FTP, HTTP, HTTPS, mailto 프로토콜로 제한되고, SEO 스팸을 완화하기 위해 모든 링크에 rel="nofollow" 속성이 추가됩니다.
Sanitize.fragment(html, Sanitize::Config::BASIC)
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
이미지와 표, 안전한 CSS를 포함해 훨씬 더 다양한 마크업을 허용합니다. 링크는 여전히 FTP, HTTP, HTTPS, mailto 프로토콜로 제한되며, 이미지는 HTTP와 HTTPS로 제한됩니다. 이 모드에서는 링크에 rel="nofollow"가 추가되지 않습니다.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# => '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
내장 모드가 요구 사항을 충족하지 못하는 경우, 사용자 정의 구성을 쉽게 지정할 수 있습니다:
Sanitize.fragment(html,
elements: ['a', 'span'],
attributes: {
'a' => ['href', 'title'],
'span' => ['class']
},
protocols: {
'a' => {'href' => ['http', 'https', 'mailto']}
}
)
Sanitize의 내장 구성 중 하나로 시작한 다음 필요에 맞게 사용자 지정할 수도 있습니다.
내장 구성은 (실수든 악의적이든) 사람들이 수정하는 것을 방지하기 위해 깊게 동결되어 있습니다. 내장 구성을 사용자 지정하려면 다음과 같이 Sanitize::Config.merge()를 사용하여 새 복사본을 만드십시오:
# Create a customized copy of the Basic config, adding <div> and <table> to the
# existing allowlisted elements.
Sanitize.fragment(html, Sanitize::Config.merge(Sanitize::Config::BASIC,
elements: Sanitize::Config::BASIC[:elements] + ['div', 'table'],
remove_contents: true
))
위 예제는 Sanitize::Config::BASIC에 있는 기존 요소 목록의 복사본에 <div> 및 <table> 요소를 추가합니다. 대신 요소 배열을 자신만의 배열로 완전히 덮어쓰려면 + 연산을 생략할 수 있습니다:
# Overwrite :elements instead of creating a copy with new entries.
Sanitize.fragment(html, Sanitize::Config.merge(Sanitize::Config::BASIC,
elements: ['div', 'table'],
remove_contents: true
))
특정 요소에 추가할 속성입니다. 속성이 이미 존재하는 경우 여기에 지정된 값으로 대체됩니다. 모든 요소 이름과 속성은 소문자로 지정하세요.
add_attributes: {
'a' => {'rel' => 'nofollow'}
}
HTML 주석 허용 여부입니다. IE는 조건부 주석 내에서 스크립트 실행을 허용하므로 주석 허용은 강력히 권장되지 않습니다. 기본값은 false입니다.
문서를 정리(sanitize)할 때 ""과 같은 올바른 형식의 HTML doctype 선언을 허용할지 여부입니다. 이 설정은 프래그먼트를 정리할 때는 무시됩니다. 기본값은 false입니다.
특정 요소에 허용할 속성입니다. 모든 요소 이름과 속성은 소문자로 지정하세요.
attributes: {
'a' => ['href', 'title'],
'blockquote' => ['cite'],
'img' => ['alt', 'src', 'title']
}
모든 요소에 특정 속성을 허용하려면 요소 이름 대신 :all 기호를 사용하세요.
# Allow the class attribute on all elements.
attributes: {
:all => ['class'],
'a' => ['href', 'title']
}
임의의 HTML5 data-* 속성을 허용하려면 속성 이름 대신 :data 기호를 사용하세요.
# Allow arbitrary HTML5 data-* attributes on <div> elements.
attributes: {
'div' => [:data]
}
CSS를 정리할 때(독립 실행형이든 HTML에 포함된 경우든) 사용할 CSS 구성 설정의 해시입니다.
CSS 주석 허용 여부입니다. 기본값은 false입니다.