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));
}