doortts doortts 2017-01-16
sanitize: Change markdown text sanitizing method
Before:
xss.js with jvm javascript engine

After:
OWASP Java HTML Sanitizer
https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project

Reason:
xss.js is too buggy and not maintained anymore.
@8683d3559fc46364a9bd482b0c3d6a35f7ad4862
app/controllers/UserApp.java
--- app/controllers/UserApp.java
+++ app/controllers/UserApp.java
@@ -52,6 +52,7 @@
 
 import static play.data.Form.form;
 import static play.libs.Json.toJson;
+import static utils.HtmlUtil.defaultSanitize;
 
 public class UserApp extends Controller {
     public static final String SESSION_USERID = "userId";
@@ -663,7 +664,7 @@
     public static Result editUserInfo() {
         Form<User> userForm = new Form<>(User.class).bindFromRequest("name", "email");
         String newEmail = userForm.data().get("email");
-        String newName = userForm.data().get("name");
+        String newName = defaultSanitize(userForm.data().get("name"));
         User user = UserApp.currentUser();
 
         if (StringUtils.isEmpty(newEmail)) {
app/models/User.java
--- app/models/User.java
+++ app/models/User.java
@@ -49,6 +49,8 @@
 import java.text.SimpleDateFormat;
 import java.util.*;
 
+import static utils.HtmlUtil.defaultSanitize;
+
 @Table(name = "n4user")
 @Entity
 public class User extends Model implements ResourceConvertible {
@@ -252,6 +254,7 @@
      */
     public static Long create(User user) {
         user.createdDate = JodaDateUtil.now();
+        user.name = defaultSanitize(user.name);
         user.save();
         CacheStore.yonaUsers.put(user.id, user);
         return user.id;
@@ -642,7 +645,7 @@
         lastStateModifiedDate = new Date();
 
         if (this.state == UserState.DELETED) {
-            name = "DELETED";
+            name = "[DELETED]" + this.name;
             oldPassword = "";
             password = "";
             passwordSalt = "";
app/utils/HtmlUtil.java
--- app/utils/HtmlUtil.java
+++ app/utils/HtmlUtil.java
@@ -1,6 +1,8 @@
 package utils;
 
 import org.apache.commons.lang.StringUtils;
+import org.owasp.html.PolicyFactory;
+import org.owasp.html.Sanitizers;
 
 /**
  * Yobi, Project Hosting SW
@@ -23,6 +25,17 @@
  * limitations under the License.
  */
 public class HtmlUtil {
+    /**
+     * Just plain default sanitize
+     * eg. It is used when user change their name.
+     * @param source
+     * @return sanitized text
+     */
+    public static String defaultSanitize(String source){
+        PolicyFactory policy = Sanitizers.FORMATTING;
+        return  policy.sanitize(source);
+    }
+
     public static String boolToCheckedString(boolean bool){
         if (bool == true) {
             return "checked";
app/utils/Markdown.java
--- app/utils/Markdown.java
+++ app/utils/Markdown.java
@@ -27,6 +27,9 @@
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.owasp.html.HtmlPolicyBuilder;
+import org.owasp.html.PolicyFactory;
+import org.owasp.html.Sanitizers;
 
 import javax.annotation.Nonnull;
 import javax.script.Invocable;
@@ -44,6 +47,15 @@
     private static final String MARKED_JS_FILE = "public/javascripts/lib/marked.js";
     private static final String HIGHLIGHT_JS_FILE = "public/javascripts/lib/highlight/highlight.pack.js";
     private static ScriptEngine engine = buildEngine();
+    private static PolicyFactory sanitizerPolicy = Sanitizers.FORMATTING
+            .and(Sanitizers.LINKS)
+            .and(Sanitizers.IMAGES)
+            .and(Sanitizers.STYLES)
+            .and(Sanitizers.TABLES)
+            .and(Sanitizers.BLOCKS)
+            .and(new HtmlPolicyBuilder().allowElements("pre").toFactory())
+            .and(new HtmlPolicyBuilder()
+                    .allowAttributes("class", "id").globally().toFactory());
 
     private static ScriptEngine buildEngine() {
         ScriptEngineManager manager = new ScriptEngineManager();
@@ -123,12 +135,7 @@
     }
 
     private static String sanitize(String source) {
-        try {
-            Object filter = engine.eval("new Filter();");
-            return (String) ((Invocable) engine).invokeMethod(filter, "defence", source);
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
+        return  sanitizerPolicy.sanitize(source);
     }
 
     private static String renderWithHighlight(String source, boolean breaks) {
build.sbt
--- build.sbt
+++ build.sbt
@@ -12,6 +12,9 @@
   javaEbean,
   javaWs,
   cache,
+  // OWASP Java HTML Sanitizer
+  // https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project
+  "com.googlecode.owasp-java-html-sanitizer" % "owasp-java-html-sanitizer" % "20160628.1",
   // Add your project dependencies here,
   "com.h2database" % "h2" % "1.3.176",
   // JDBC driver for mariadb
Add a comment
List