Author: lryan
Date: Tue Jun 30 16:16:20 2009
New Revision: 789818

URL: http://svn.apache.org/viewvc?rev=789818&view=rev
Log:
Fix CSS sanitization to properly sanitize image references.

Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizer.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingRequestRewriter.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizerTest.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizer.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizer.java?rev=789818&r1=789817&r2=789818&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizer.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizer.java
 Tue Jun 30 16:16:20 2009
@@ -66,12 +66,14 @@
    * Sanitize the CSS content of a style tag.
    * @param content to sanitize
    * @param linkContext url of containing content
-   * @param importRewriter to rewrite links to sanitizing proxy
+   * @param importRewriter to rewrite @imports to sanitizing proxy
+   * @param importRewriter to rewrite images to sanitizing proxy
    */
-  public String sanitize(String content, Uri linkContext, LinkRewriter 
importRewriter) {
+  public String sanitize(String content, Uri linkContext, LinkRewriter 
importRewriter,
+      LinkRewriter imageRewriter) {
     try {
       CssTree.StyleSheet stylesheet = parser.parseDom(content);
-      sanitize(stylesheet, linkContext, importRewriter);
+      sanitize(stylesheet, linkContext, importRewriter, imageRewriter);
       // Write the rewritten CSS back into the element
       return parser.serialize(stylesheet);
     } catch (GadgetException ge) {
@@ -85,13 +87,15 @@
    * Sanitize the CSS content of a style tag.
    * @param styleElem to sanitize
    * @param linkContext url of containing content
-   * @param importRewriter to rewrite links to sanitizing proxy
+   * @param importRewriter to rewrite @imports to sanitizing proxy
+   * @param importRewriter to rewrite images to sanitizing proxy
    */
-  public void sanitize(Element styleElem, Uri linkContext, LinkRewriter 
importRewriter) {
+  public void sanitize(Element styleElem, Uri linkContext, LinkRewriter 
importRewriter,
+      LinkRewriter imageRewriter) {
     String content = null;
     try {
       CssTree.StyleSheet stylesheet = 
parser.parseDom(styleElem.getTextContent());
-      sanitize(stylesheet, linkContext, importRewriter);
+      sanitize(stylesheet, linkContext, importRewriter, imageRewriter);
       // Write the rewritten CSS back into the element
       content = parser.serialize(stylesheet);
     } catch (GadgetException ge) {
@@ -111,8 +115,10 @@
    * @param css DOM root
    * @param linkContext url of containing content
    * @param importRewriter to rewrite links to sanitizing proxy
+   * @param imageRewriter to rewrite links to the sanitizing proxy
    */
-  public void sanitize(CssTree css, final Uri linkContext, final LinkRewriter 
importRewriter) {
+  public void sanitize(CssTree css, final Uri linkContext, final LinkRewriter 
importRewriter,
+      final LinkRewriter imageRewriter) {
     css.acceptPreOrder(new Visitor() {
       public boolean visit(AncestorChain<?> ancestorChain) {
         if (ancestorChain.node instanceof CssTree.Property) {
@@ -134,7 +140,8 @@
             }
             clean(ancestorChain);
           }
-        } else if (ancestorChain.node instanceof CssTree.UriLiteral) {
+        } else if (ancestorChain.node instanceof CssTree.UriLiteral &&
+            !(ancestorChain.getParentNode() instanceof CssTree.Import)) {
           boolean validUri = false;
           String uri = ((CssTree.UriLiteral)ancestorChain.node).getValue();
           try {
@@ -153,6 +160,10 @@
                   + ((CssTree.UriLiteral) ancestorChain.node).getValue());
             }
             clean(ancestorChain);
+          } else {
+            // Assume the URI is for an image. Rewrite it using the image link 
rewriter
+            ((CssTree.UriLiteral)ancestorChain.node).setValue(
+                imageRewriter.rewrite(uri, linkContext));
           }
         } else if (ancestorChain.node instanceof CssTree.Import) {
           CssTree.Import importDecl = (CssTree.Import) ancestorChain.node;

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java?rev=789818&r1=789817&r2=789818&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingGadgetRewriter.java
 Tue Jun 30 16:16:20 2009
@@ -148,7 +148,7 @@
           rewriterFeatureFactory.createRewriteAllFeature(expires == null ? -1 
: expires);
 
       String proxyBaseNoGadget = 
rewriterUris.getProxyBase(gadget.getContext().getContainer());
-      LinkRewriter cssRewriter = new 
SanitizingProxyingLinkRewriter(gadget.getSpec().getUrl(),
+      LinkRewriter cssImportRewriter = new 
SanitizingProxyingLinkRewriter(gadget.getSpec().getUrl(),
           rewriterFeature, proxyBaseNoGadget, "text/css");
       LinkRewriter imageRewriter = new 
SanitizingProxyingLinkRewriter(gadget.getSpec().getUrl(),
           rewriterFeature, proxyBaseNoGadget, "image/*");
@@ -157,8 +157,8 @@
       filters = ImmutableList.of(
         new BasicElementFilter(allowedTags, allowedAttributes),
         new LinkSchemeCheckFilter(),
-        new StyleFilter(cssSanitizer, cssRewriter),
-        new LinkFilter(cssRewriter),
+        new StyleFilter(cssSanitizer, cssImportRewriter, imageRewriter),
+        new LinkFilter(cssImportRewriter),
         new ImageFilter(imageRewriter),
         new TargetFilter()
       );
@@ -354,16 +354,19 @@
    */
   static class StyleFilter implements DomFilter {
     final CajaCssSanitizer sanitizer;
-    final LinkRewriter rewriter;
+    final LinkRewriter importRewriter;
+    final LinkRewriter imageRewriter;
 
-    StyleFilter(CajaCssSanitizer sanitizer, LinkRewriter rewriter) {
+    StyleFilter(CajaCssSanitizer sanitizer, LinkRewriter importRewriter,
+        LinkRewriter imageRewriter) {
       this.sanitizer = sanitizer;
-      this.rewriter = rewriter;
+      this.importRewriter = importRewriter;
+      this.imageRewriter = imageRewriter;
     }
 
     public Result filterTag(Element elem, Uri context) {
       if ("style".equalsIgnoreCase(elem.getNodeName())) {
-        sanitizer.sanitize(elem, context, rewriter);
+        sanitizer.sanitize(elem, context, importRewriter, imageRewriter);
       }
       return Result.PASS;
     }

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingRequestRewriter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingRequestRewriter.java?rev=789818&r1=789817&r2=789818&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingRequestRewriter.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/SanitizingRequestRewriter.java
 Tue Jun 30 16:16:20 2009
@@ -129,9 +129,12 @@
       String contentType = response.getHeader("Content-Type");
       if (contentType == null || 
contentType.toLowerCase().startsWith("text/")) {
         String proxyBaseNoGadget = 
rewriterUris.getProxyBase(request.getContainer());
-        SanitizingProxyingLinkRewriter cssLinkRewriter = new 
SanitizingProxyingLinkRewriter(
+        SanitizingProxyingLinkRewriter cssImportRewriter = new 
SanitizingProxyingLinkRewriter(
             request.getGadget(), rewriterFeature, proxyBaseNoGadget, 
"text/css");
-        sanitized = cssSanitizer.sanitize(content.getContent(), 
request.getUri(), cssLinkRewriter);
+        SanitizingProxyingLinkRewriter cssImageRewriter = new 
SanitizingProxyingLinkRewriter(
+            request.getGadget(), rewriterFeature, proxyBaseNoGadget, 
"image/*");
+        sanitized = cssSanitizer.sanitize(content.getContent(), 
request.getUri(), cssImportRewriter,
+            cssImageRewriter);
       }
       
       return true;

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizerTest.java?rev=789818&r1=789817&r2=789818&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizerTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/caja/CajaCssSanitizerTest.java
 Tue Jun 30 16:16:20 2009
@@ -32,16 +32,22 @@
   private CajaCssParser parser;
   private CajaCssSanitizer sanitizer;
   private final Uri DUMMY = Uri.parse("http://www.example.org/base";);
-  private LinkRewriter fakeRewriter;
+  private LinkRewriter importRewriter;
+  private LinkRewriter imageRewriter;
 
   @Override
   protected void setUp() throws Exception {
     super.setUp();
     parser = new CajaCssParser();
     sanitizer = new CajaCssSanitizer(parser);
-    fakeRewriter = new LinkRewriter() {
+    importRewriter = new LinkRewriter() {
       public String rewrite(String link, Uri context) {
-        return link + "&" + ProxyBase.SANITIZE_CONTENT_PARAM + "=1";
+        return link + "&" + ProxyBase.SANITIZE_CONTENT_PARAM + 
"=1&rewriteMime=text/css";
+      }
+    };
+    imageRewriter = new LinkRewriter() {
+      public String rewrite(String link, Uri context) {
+        return link + "&" + ProxyBase.SANITIZE_CONTENT_PARAM + 
"=1&rewriteMime=image/*";
       }
     };
   }
@@ -49,31 +55,39 @@
   public void testPreserveSafe() throws Exception {
     String css = ".xyz { font: bold;} A { color: #7f7f7f}";
     CssTree.StyleSheet styleSheet = parser.parseDom(css);
-    sanitizer.sanitize(styleSheet, DUMMY, fakeRewriter);
+    sanitizer.sanitize(styleSheet, DUMMY, importRewriter, imageRewriter);
     assertStyleEquals(css, styleSheet);
   }
 
   public void testSanitizeFunctionCall() throws Exception {
     String css = ".xyz { font : iamevil(bold); }";
     CssTree.StyleSheet styleSheet = parser.parseDom(css);
-    sanitizer.sanitize(styleSheet, DUMMY, fakeRewriter);
+    sanitizer.sanitize(styleSheet, DUMMY, importRewriter, imageRewriter);
     assertStyleEquals(".xyz {}", styleSheet);
   }
 
    public void testSanitizeUnsafeProperties() throws Exception {
     String css = ".xyz { behavior: url('xyz.htc'); 
-moz-binding:url(\"http://ha.ckers.org/xssmoz.xml#xss\";) }";
     CssTree.StyleSheet styleSheet = parser.parseDom(css);
-    sanitizer.sanitize(styleSheet, DUMMY, fakeRewriter);
+    sanitizer.sanitize(styleSheet, DUMMY, importRewriter, imageRewriter);
     assertStyleEquals(".xyz {}", styleSheet);
   }
 
   public void testSanitizeScriptUrls() throws Exception {
     String css = ".xyz { background: url('javascript:doevill'); background : 
url(vbscript:moreevil); }";
     CssTree.StyleSheet styleSheet = parser.parseDom(css);
-    sanitizer.sanitize(styleSheet, DUMMY, fakeRewriter);
+    sanitizer.sanitize(styleSheet, DUMMY, importRewriter, imageRewriter);
     assertStyleEquals(".xyz {}", styleSheet);
   }
 
+  public void testProxyUrls() throws Exception {
+    String css = ".xyz { background: url('http://www.example.org/img.gif');}";
+    CssTree.StyleSheet styleSheet = parser.parseDom(css);
+    sanitizer.sanitize(styleSheet, DUMMY, importRewriter, imageRewriter);
+    assertStyleEquals(
+        ".xyz { background: 
url('http://www.example.org/img.gif\\26sanitize%3d1\\26rewriteMime%3dimage/\\2A 
');}", styleSheet);
+  }
+
   public void assertStyleEquals(String expected, CssTree.StyleSheet 
styleSheet) throws Exception {
     assertEquals(parser.serialize(parser.parseDom(expected)), 
parser.serialize(styleSheet));
   }


Reply via email to