This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.xss-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-xss.git

commit 675462e985395be0d8789eef1366883f6bdc1a9e
Author: Felix Meschberger <[email protected]>
AuthorDate: Wed Nov 19 09:01:54 2014 +0000

    SLING-4176 - Added validation/filtering for StyleToken context
    
    * Adding a new method for checking CSS tokens to the XSSAPI
    * Incl. implementation and unit tests
    
    This closes #38
    
    (Applying patch by Vlad Bailescue; Thanks alot)
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/contrib/xss@1640505 
13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/java/org/apache/sling/xss/XSSAPI.java     | 10 +++
 .../java/org/apache/sling/xss/impl/XSSAPIImpl.java | 40 ++++++++++
 .../org/apache/sling/xss/impl/XSSAPIImplTest.java  | 88 +++++++++++++++++++---
 3 files changed, 128 insertions(+), 10 deletions(-)

diff --git a/src/main/java/org/apache/sling/xss/XSSAPI.java 
b/src/main/java/org/apache/sling/xss/XSSAPI.java
index b447324..09801a6 100644
--- a/src/main/java/org/apache/sling/xss/XSSAPI.java
+++ b/src/main/java/org/apache/sling/xss/XSSAPI.java
@@ -86,6 +86,16 @@ public interface XSSAPI {
     public String getValidJSToken(String token, String defaultValue);
 
     /**
+     * Validate a style/CSS token. Valid CSS tokens are specified at 
http://www.w3.org/TR/css3-syntax/
+     *
+     * @param token        the source token
+     * @param defaultValue a default value to use if the source doesn't meet 
validity constraints.
+     *
+     * @return a string containing sanitized style token
+     */
+    public String getValidStyleToken(String token, String defaultValue);
+
+    /**
      * Validate a CSS color value. Color values as specified at 
http://www.w3.org/TR/css3-color/#colorunits
      * are safe and definitively allowed. Vulnerable constructs will be 
disallowed. Currently known
      * vulnerable constructs include url(...), expression(...), and anything 
with a semicolon.
diff --git a/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java 
b/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java
index 034a38d..4306d99 100644
--- a/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java
+++ b/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java
@@ -190,6 +190,46 @@ public class XSSAPIImpl implements XSSAPI {
         }
     }
 
+    private static final String NON_ASCII = "\\x00\\x08\\x0B\\x0C\\x0E-\\x1F";
+    /** http://www.w3.org/TR/css-syntax-3/#number-token-diagram */
+    private static final String NUMBER = 
"[+-]?[\\d]*[\\.]?[\\d]*(?:[e][+-]?\\d+)?";
+    /** http://www.w3.org/TR/css-syntax-3/#hex-digit-diagram */
+    private static final String HEX_DIGITS = "#[0-9a-f]*";
+    /** http://www.w3.org/TR/css-syntax-3/#ident-token-diagram */
+    private static final String IDENTIFIER = "-?[a-z_" + NON_ASCII + 
"][\\w_\\-" + NON_ASCII + "]*";
+    /** http://www.w3.org/TR/css-syntax-3/#string-token-diagram */
+    private static final String STRING = 
"\"(?:[^\"^\\\\^\\n]|(?:\\\\\"))*\"|'(?:[^'^\\\\^\\n]|(?:\\\\'))*'";
+    /** http://www.w3.org/TR/css-syntax-3/#dimension-token-diagram */
+    private static final String DIMENSION = NUMBER + IDENTIFIER;
+    /** http://www.w3.org/TR/css-syntax-3/#percentage-token-diagram */
+    private static final String PERCENT = NUMBER + "%";
+    /** http://www.w3.org/TR/css-syntax-3/#function-token-diagram */
+    private static final String FUNCTION = IDENTIFIER + "\\((?:(?:" + NUMBER + 
")|(?:" + IDENTIFIER + ")|(?:[\\s]*)|(?:,))*\\)";
+    /** http://www.w3.org/TR/css-syntax-3/#url-unquoted-diagram */
+    private static final String URL_UNQUOTED = "[^\"^'^\\(^\\)^[" + NON_ASCII 
+ "]]*";
+    /** http://www.w3.org/TR/css-syntax-3/#url-token-diagram */
+    private static final String URL = "url\\((?:(?:" + URL_UNQUOTED + ")|(?:" 
+ STRING + "))\\)";
+    /** composite regular expression for style token validation */
+    private static final String CSS_TOKEN = "(?i)" // case insensitive
+            + "(?:" + NUMBER + ")"
+            + "|(?:" + DIMENSION + ")"
+            + "|(?:" + PERCENT + ")"
+            + "|(?:" + HEX_DIGITS + ")"
+            + "|(?:" + IDENTIFIER + ")"
+            + "|(?:" + STRING + ")"
+            + "|(?:" + FUNCTION + ")"
+            + "|(?:" + URL + ")";
+
+    /**
+     * @see org.apache.sling.xss.XSSAPI#getValidStyleToken(String, String)
+     */
+    public String getValidStyleToken(String token, String defaultValue) {
+        if (token.matches(CSS_TOKEN)) {
+            return token;
+        }
+        return defaultValue;
+    }
+
     /**
      * @see org.apache.sling.xss.XSSAPI#getValidCSSColor(String, String)
      */
diff --git a/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java 
b/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java
index 9637da6..3f7108c 100644
--- a/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java
+++ b/src/test/java/org/apache/sling/xss/impl/XSSAPIImplTest.java
@@ -39,6 +39,8 @@ import org.owasp.validator.html.Policy;
 
 public class XSSAPIImplTest {
 
+    public static final String RUBBISH = "rubbish";
+
     private XSSAPI xssAPI;
 
     @Before
@@ -310,25 +312,25 @@ public class XSSAPIImplTest {
                 {"simple", "simple"},
                 {"clickstreamcloud.thingy", "clickstreamcloud.thingy"},
 
-                {"break out", "rubbish"},
-                {"break,out", "rubbish"},
+                {"break out", RUBBISH},
+                {"break,out", RUBBISH},
 
                 {"\"literal string\"", "\"literal string\""},
                 {"'literal string'", "'literal string'"},
-                {"\"bad literal'", "rubbish"},
+                {"\"bad literal'", RUBBISH},
                 {"'literal'); junk'", "'literal\\x27); junk'"},
 
                 {"1200", "1200"},
                 {"3.14", "3.14"},
-                {"1,200", "rubbish"},
-                {"1200 + 1", "rubbish"}
+                {"1,200", RUBBISH},
+                {"1200 + 1", RUBBISH}
         };
 
         for (String[] aTestData : testData) {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.getValidJSToken(source, "rubbish");
+            String result = xssAPI.getValidJSToken(source, RUBBISH);
             if (!result.equals(expected)) {
                 fail("Validating Javascript token '" + source + "', expecting 
'" + expected + "', but got '" + result + "'");
             }
@@ -336,6 +338,72 @@ public class XSSAPIImplTest {
     }
 
     @Test
+    public void TestGetValidStyleToken() {
+        String[][] testData = {
+                // Source                           Expected result
+
+                // CSS close
+                {"}"                                , RUBBISH},
+
+                // line break
+                {"br\neak"                          , RUBBISH},
+
+                // no javascript:
+                {"javascript:alert(1)"              , RUBBISH},
+                {"url(javascript:alert(1))"         , RUBBISH},
+
+                // no expression
+                {"expression(alert(1))"             , RUBBISH},
+                {"expression  (alert(1))"           , RUBBISH},
+                {"expression(this.location='a.co')" , RUBBISH},
+
+                // html tags
+                {"</style><script>alert(1)</script>", RUBBISH},
+
+                // usual CSS stuff
+                {"background-color"                 , "background-color"},
+                {"-moz-box-sizing"                  , "-moz-box-sizing"},
+                {".42%"                             , ".42%"},
+                {"#fff"                             , "#fff"},
+
+                // valid strings
+                {"'literal string'"                 , "'literal string'"},
+                {"\"literal string\""               , "\"literal string\""},
+                {"'it\\'s here'"                    , "'it\\'s here'"},
+                {"\"it\\\"s here\""                 , "\"it\\\"s here\""},
+
+                // invalid strings
+                {"\"bad string"                     , RUBBISH},
+                {"'it's here'"                      , RUBBISH},
+                {"\"it\"s here\""                   , RUBBISH},
+
+                // valid parenthesis
+                {"rgb(255, 255, 255)"               , "rgb(255, 255, 255)"},
+
+                // invalid parenthesis
+                {"rgb(255, 255, 255"               , RUBBISH},
+                {"255, 255, 255)"                  , RUBBISH},
+
+                // valid tokens
+                {"url(http://example.com/test.png)", 
"url(http://example.com/test.png)"},
+                {"url('image/test.png')"           , "url('image/test.png')"},
+
+                // invalid tokens
+                {"color: red"                      , RUBBISH}
+        };
+
+        for (String[] aTestData : testData) {
+            String source = aTestData[0];
+            String expected = aTestData[1];
+
+            String result = xssAPI.getValidStyleToken(source, RUBBISH);
+            if (!result.equals(expected)) {
+                fail("Validating style token '" + source + "', expecting '" + 
expected + "', but got '" + result + "'");
+            }
+        }
+    }
+
+    @Test
     public void TestGetValidCSSColor() {
         String[][] testData = {
                 //      Source                          Expected Result
@@ -352,16 +420,16 @@ public class XSSAPIImplTest {
                 {"transparent", "transparent"},
 
                 {"\f\r\n\t MenuText\f\r\n\t ", "MenuText"},
-                {"expression(99,99,99)", "rubbish"},
-                {"blue;", "rubbish"},
-                {"url(99,99,99)", "rubbish"}
+                {"expression(99,99,99)", RUBBISH},
+                {"blue;", RUBBISH},
+                {"url(99,99,99)", RUBBISH}
         };
 
         for (String[] aTestData : testData) {
             String source = aTestData[0];
             String expected = aTestData[1];
 
-            String result = xssAPI.getValidCSSColor(source, "rubbish");
+            String result = xssAPI.getValidCSSColor(source, RUBBISH);
             if (!result.equals(expected)) {
                 fail("Validating CSS Color '" + source + "', expecting '" + 
expected + "', but got '" + result + "'");
             }

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to