diff --git a/src/main/java/nlib/util/StringUtil.java b/src/main/java/nlib/util/StringUtil.java
index dd945d76..a8fb28ab 100644
--- a/src/main/java/nlib/util/StringUtil.java
+++ b/src/main/java/nlib/util/StringUtil.java
@@ -11,6 +11,7 @@ import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.Locale;
+import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.owasp.html.HtmlPolicyBuilder;
@@ -18,6 +19,8 @@ import org.owasp.html.PolicyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Predicate;
+
import nlib.cmm.service.NlibProperty;
/**
@@ -423,36 +426,7 @@ public class StringUtil extends StringUtils {
return value;
}
-
- /**
- * XSS 등의 공격으로 부터 보안성 유지를 위해서 HTML 허용된 태그와 속성만으로 HTML을 재구성하여 리턴한다.
- *
- * @param html
- * @return
- */
- public static String sanitizeHtml(String html) {
-
- if(isEmpty(html)) return html;
- PolicyFactory policy = new HtmlPolicyBuilder()
- .allowAttributes("src", "align", "title").onElements("img")
- .allowAttributes("href", "title").onElements("a")
- .allowAttributes("class", "height", "width", "style").globally()
- .allowUrlProtocols("http","https","mailto","tel")
- .allowElements(
- "a", "label",
- "h1", "h2", "h3", "h4", "h5", "h6",
- "p", "i", "b", "u", "strong", "em", "small", "big", "pre", "code",
- "cite", "samp", "sub", "sup", "strike", "center", "blockquote",
- "hr", "br", "col", "font", "span", "div", "img",
- "ul", "ol", "li", "dd", "dt", "dl", "tbody", "thead", "tfoot",
- "table", "td", "th", "tr", "colgroup", "fieldset", "legend"
- )
- .toFactory();
-
- return policy.sanitize(html);
- }
-
// Tag 화이트 리스트 ( 허용할 태그 등록 )
static String[] whiteListTag = { "
","
","
" };
@@ -494,4 +468,61 @@ public class StringUtil extends StringUtils {
return false;
}
+ /*
+ ************************************************************************************************
+ * OWASP HTML SANITIZING 관련 : 시작
+ ************************************************************************************************
+ */
+ private static final Pattern ONSITE_URL = Pattern.compile("(?:[\\p{L}\\p{N}\\\\\\.\\#@\\$%\\+&;\\-_~,\\?=/!]+|\\#(\\w)+)");
+ private static final Pattern OFFSITE_URL = Pattern.compile("\\s*(?:(?:ht|f)tps?://|mailto:)[\\p{L}\\p{N}]"
+ + "[\\p{L}\\p{N}\\p{Zs}\\.\\#@\\$%\\+&;:\\-_~,\\?=/!\\(\\)]*+\\s*");
+ private static final Pattern EMBED_URL = Pattern.compile("^.*data:image/.*$");
+
+ private static final Predicate ONSITE_OR_OFFSITE_URL = matchesEither(ONSITE_URL, OFFSITE_URL, EMBED_URL);
+
+ /**
+ * XSS 등의 공격으로 부터 보안성 유지를 위해서 HTML 허용된 태그와 속성만으로 HTML을 재구성하여 리턴한다.
+ *
+ * @param html
+ * @return
+ */
+ public static String sanitizeHtml(String html) {
+
+ if(isEmpty(html)) return html;
+
+ PolicyFactory policy = new HtmlPolicyBuilder()
+ .allowAttributes("src", "align", "title").onElements("img")
+ .allowAttributes("href", "title").onElements("a")
+ .allowAttributes("class", "height", "width", "style").globally()
+ .allowUrlProtocols("http","https","mailto","tel","data")
+ .allowAttributes("src").matching(ONSITE_OR_OFFSITE_URL).onElements("img")
+ .allowAttributes("src").matching(Pattern.compile("^.*data:image/.*$")).onElements("img")
+ .allowElements(
+ "a", "label",
+ "h1", "h2", "h3", "h4", "h5", "h6",
+ "p", "i", "b", "u", "strong", "em", "small", "big", "pre", "code",
+ "cite", "samp", "sub", "sup", "strike", "center", "blockquote",
+ "hr", "br", "col", "font", "span", "div", "img",
+ "ul", "ol", "li", "dd", "dt", "dl", "tbody", "thead", "tfoot",
+ "table", "td", "th", "tr", "colgroup", "fieldset", "legend"
+ )
+ .toFactory();
+
+ return policy.sanitize(html);
+ }
+
+ private static Predicate matchesEither(final Pattern a, final Pattern b, final Pattern c) {
+ return new Predicate() {
+ public boolean apply(String s) {
+ return a.matcher(s).matches() || b.matcher(s).matches() || c.matcher(s).matches();
+ }
+ };
+ }
+
+ /*
+ ************************************************************************************************
+ * OWASP HTML SANITIZING 관련 : 종료
+ ************************************************************************************************
+ */
+
}