/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package org.apache.shindig.gadgets.parse.caja; import com.google.caja.parser.css.CssTree; import com.google.common.collect.ImmutableMap; import org.apache.shindig.common.EasyMockTestCase; import org.apache.shindig.common.uri.Uri; import org.apache.shindig.config.AbstractContainerConfig; import org.apache.shindig.config.ContainerConfig; import org.apache.shindig.gadgets.GadgetContext; import org.apache.shindig.gadgets.render.SanitizingProxyUriManager; import org.apache.shindig.gadgets.uri.DefaultProxyUriManager; import org.apache.shindig.gadgets.uri.ProxyUriManager; import org.junit.Before; import org.junit.Test; import java.util.HashMap; import java.util.Map; /** * Tests for CajaCssSanitizer. */ public class CajaCssSanitizerTest extends EasyMockTestCase { private CajaCssParser parser; private CajaCssSanitizer sanitizer; private final Uri DUMMY = Uri.parse("http://www.example.org/base"); private SanitizingProxyUriManager importRewriter; private SanitizingProxyUriManager imageRewriter; private GadgetContext gadgetContext; public static final String MOCK_CONTAINER = "mockContainer"; private static class FakeContainerConfig extends AbstractContainerConfig { private Map<String, Map<String, Object>> containers = new HashMap<String, Map<String, Object>>(); private FakeContainerConfig() { containers.put(ContainerConfig.DEFAULT_CONTAINER, ImmutableMap.<String, Object>builder() .put(DefaultProxyUriManager.PROXY_HOST_PARAM, "www.test.com") .put(DefaultProxyUriManager.PROXY_PATH_PARAM, "/dir/proxy") .build()); containers.put(MOCK_CONTAINER, ImmutableMap.<String, Object>builder() .put(DefaultProxyUriManager.PROXY_HOST_PARAM, "www.mock.com") .build()); } @Override public Object getProperty(String container, String name) { Map<String, Object> data = containers.get(container); // Inherit from default if there is no value for this key. if (!data.containsKey(name)) { data = containers.get(ContainerConfig.DEFAULT_CONTAINER); } return data.get(name); } } @Before public void setUp() throws Exception { parser = new CajaCssParser(); sanitizer = new CajaCssSanitizer(parser); ContainerConfig config = new FakeContainerConfig(); ProxyUriManager proxyUriManager = new DefaultProxyUriManager(config, null); importRewriter = new SanitizingProxyUriManager(proxyUriManager, "text/css"); imageRewriter = new SanitizingProxyUriManager(proxyUriManager, "image/*"); gadgetContext = new GadgetContext() { @Override public String getContainer() { return MOCK_CONTAINER; } }; } @Test public void testPreserveSafe() throws Exception { String css = ".xyz { font: bold;} A { color: #7f7f7f}"; CssTree.StyleSheet styleSheet = parser.parseDom(css); sanitizer.sanitize(styleSheet, DUMMY, gadgetContext, importRewriter, imageRewriter); assertStyleEquals(css, styleSheet); } @Test public void testSanitizeFunctionCall() throws Exception { String css = ".xyz { font : iamevil(bold); }"; CssTree.StyleSheet styleSheet = parser.parseDom(css); sanitizer.sanitize(styleSheet, DUMMY, gadgetContext, importRewriter, imageRewriter); assertStyleEquals(".xyz {}", styleSheet); } @Test 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, gadgetContext, importRewriter, imageRewriter); assertStyleEquals(".xyz {}", styleSheet); } @Test 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, gadgetContext, importRewriter, imageRewriter); assertStyleEquals(".xyz {}", styleSheet); } @Test 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, gadgetContext, importRewriter, imageRewriter); assertStyleEquals(".xyz { " + "background: url('//www.mock.com/dir/proxy?container=mockContainer&gadget=http%3A%2F%2Fwww.example.org%2Fbase" + "&debug=0&nocache=0&url=http%3A%2F%2Fwww.example.org%2Fimg.gif&" + "sanitize=1&rewriteMime=image%2F%2a');}", styleSheet); } @Test public void testUrlEscapingMockContainer() throws Exception { String css = ".xyz { background: url('http://www.example.org/img.gif');}"; CssTree.StyleSheet styleSheet = parser.parseDom(css); sanitizer.sanitize(styleSheet, DUMMY, gadgetContext, importRewriter, imageRewriter); assertEquals(".xyz{" + "background:url('//www.mock.com/dir/proxy?container=mockContainer&gadget=http%3A%2F%2Fwww.example.org%2Fbase" + "&debug=0&nocache=0&url=http%3A%2F%2Fwww.example.org%2Fimg.gif" + "&sanitize=1&rewriteMime=image%2F%2a');}", parser.serialize(styleSheet).replaceAll("\\s", "")); } @Test public void testUrlEscapingDefaultContainer() throws Exception { String css = ".xyz { background: url('http://www.example.org/img.gif');}"; CssTree.StyleSheet styleSheet = parser.parseDom(css); GadgetContext gadgetContext = new GadgetContext() { @Override public String getContainer() { return ContainerConfig.DEFAULT_CONTAINER; } }; sanitizer.sanitize(styleSheet, DUMMY, gadgetContext, importRewriter, imageRewriter); assertEquals(".xyz{" + "background:url('//www.test.com/dir/proxy?container=default&gadget=http%3A%2F%2Fwww.example.org%2Fbase" + "&debug=0&nocache=0&url=http%3A%2F%2Fwww.example.org%2Fimg.gif" + "&sanitize=1&rewriteMime=image%2F%2a');}", parser.serialize(styleSheet).replaceAll("\\s", "")); } public void assertStyleEquals(String expected, CssTree.StyleSheet styleSheet) throws Exception { assertEquals(parser.serialize(parser.parseDom(expected)), parser.serialize(styleSheet)); } }