This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.xss-2.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-xss.git
commit 5097148430ce4ed2ed8a2ac9c50e40c8618cb0df Author: Radu Cotescu <[email protected]> AuthorDate: Thu Mar 30 12:10:05 2017 +0000 SLING-6754 - The XSS bundle doesn't provide any services * switched to the official OSGi annotations * minor code cleanup git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/xss@1789508 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 23 ++- src/main/java/org/apache/sling/xss/XSSAPI.java | 3 +- src/main/java/org/apache/sling/xss/XSSFilter.java | 2 +- .../sling/xss/impl/XSSAPIAdapterFactory.java | 52 +++---- .../java/org/apache/sling/xss/impl/XSSAPIImpl.java | 15 +- .../org/apache/sling/xss/impl/XSSFilterImpl.java | 165 ++++++++++----------- .../java/org/apache/sling/xss/package-info.java | 3 +- 7 files changed, 116 insertions(+), 147 deletions(-) diff --git a/pom.xml b/pom.xml index 8ecbc64..c891b5f 100644 --- a/pom.xml +++ b/pom.xml @@ -68,10 +68,6 @@ <plugins> <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-scr-plugin</artifactId> - </plugin> - <plugin> <groupId>org.apache.sling</groupId> <artifactId>maven-sling-plugin</artifactId> </plugin> @@ -79,7 +75,16 @@ <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> + <executions> + <execution> + <id>scr-metadata</id> + <goals> + <goal>manifest</goal> + </goals> + </execution> + </executions> <configuration> + <exportScr>true</exportScr> <instructions> <Import-Package> !bsh, @@ -245,16 +250,6 @@ <artifactId>osgi.core</artifactId> </dependency> <dependency> - <groupId>org.apache.felix</groupId> - <artifactId>org.apache.felix.scr.annotations</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>biz.aQute.bnd</groupId> - <artifactId>biz.aQute.bndlib</artifactId> - <scope>provided</scope> - </dependency> - <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> diff --git a/src/main/java/org/apache/sling/xss/XSSAPI.java b/src/main/java/org/apache/sling/xss/XSSAPI.java index 3a3780d..1819663 100644 --- a/src/main/java/org/apache/sling/xss/XSSAPI.java +++ b/src/main/java/org/apache/sling/xss/XSSAPI.java @@ -24,8 +24,7 @@ import javax.annotation.Nullable; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.ResourceResolver; - -import aQute.bnd.annotation.ProviderType; +import org.osgi.annotation.versioning.ProviderType; /** * A service providing validators and encoders for XSS protection during the composition of HTML diff --git a/src/main/java/org/apache/sling/xss/XSSFilter.java b/src/main/java/org/apache/sling/xss/XSSFilter.java index 86c1409..9fece46 100644 --- a/src/main/java/org/apache/sling/xss/XSSFilter.java +++ b/src/main/java/org/apache/sling/xss/XSSFilter.java @@ -16,7 +16,7 @@ ******************************************************************************/ package org.apache.sling.xss; -import aQute.bnd.annotation.ProviderType; +import org.osgi.annotation.versioning.ProviderType; /** * This service should be used to protect output against potential XSS attacks. diff --git a/src/main/java/org/apache/sling/xss/impl/XSSAPIAdapterFactory.java b/src/main/java/org/apache/sling/xss/impl/XSSAPIAdapterFactory.java index ba8a323..995d4dd 100644 --- a/src/main/java/org/apache/sling/xss/impl/XSSAPIAdapterFactory.java +++ b/src/main/java/org/apache/sling/xss/impl/XSSAPIAdapterFactory.java @@ -16,56 +16,44 @@ ******************************************************************************/ package org.apache.sling.xss.impl; -import org.apache.sling.xss.XSSAPI; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Properties; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.Service; +import javax.annotation.Nonnull; + import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.adapter.AdapterFactory; import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.xss.XSSAPI; +import org.osgi.framework.Constants; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Adapter factory that adapts a {@link ResourceResolver} to a resourceResolver-specific * {@link XSSAPI} service. */ -@Component(metatype = false) -@Service(AdapterFactory.class) -@Properties({ - @Property(name = "service.description", value = "Adapter for the XSSAPI service.") -}) -@SuppressWarnings("unused") +@Component( + property = { + Constants.SERVICE_DESCRIPTION + "=Adapter for the XSSAPI service.", + AdapterFactory.ADAPTER_CLASSES + "=org.apache.sling.xss.XSSAPI", + AdapterFactory.ADAPTABLE_CLASSES + "=org.apache.sling.api.resource.ResourceResolver", + AdapterFactory.ADAPTABLE_CLASSES + "=org.apache.sling.api.SlingHttpServletRequest" + } +) public class XSSAPIAdapterFactory implements AdapterFactory { - private static final Logger log = LoggerFactory.getLogger(XSSAPIAdapterFactory.class); - private static final Class<XSSAPI> XSSAPI_CLASS = XSSAPI.class; - private static final Class<ResourceResolver> RESOURCE_RESOLVER_CLASS = ResourceResolver.class; - private static final Class<SlingHttpServletRequest> SLING_REQUEST_CLASS = SlingHttpServletRequest.class; + + private static final Logger LOGGER = LoggerFactory.getLogger(XSSAPIAdapterFactory.class); @Reference XSSAPI xssApi; - @Property(name = "adapters") - public static final String[] ADAPTER_CLASSES = { - XSSAPI_CLASS.getName() - }; - - @Property(name = "adaptables") - public static final String[] ADAPTABLE_CLASSES = { - RESOURCE_RESOLVER_CLASS.getName(), - SLING_REQUEST_CLASS.getName() - }; - - public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) { + public <AdapterType> AdapterType getAdapter(@Nonnull Object adaptable, @Nonnull Class<AdapterType> type) { if (adaptable instanceof ResourceResolver) { return getAdapter((ResourceResolver) adaptable, type); } else if (adaptable instanceof SlingHttpServletRequest) { return getAdapter((SlingHttpServletRequest) adaptable, type); } else { - log.warn("Unable to handle adaptable {}", adaptable.getClass().getName()); + LOGGER.warn("Unable to handle adaptable {}", adaptable.getClass().getName()); return null; } } @@ -77,7 +65,7 @@ public class XSSAPIAdapterFactory implements AdapterFactory { return (AdapterType) xssApi.getResourceResolverSpecificAPI(resourceResolver); } } - log.debug("Unable to adapt resourceResolver to type {}", type.getName()); + LOGGER.error(String.format("Unable to adapt resourceResolver to type %s.", type.getName())); return null; } @@ -88,7 +76,7 @@ public class XSSAPIAdapterFactory implements AdapterFactory { return (AdapterType) xssApi.getRequestSpecificAPI(request); } } - log.debug("Unable to adapt resourceResolver to type {}", type.getName()); + LOGGER.error(String.format("Unable to adapt request to type %s.", type.getName())); return null; } } 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 d88acf5..91c648b 100644 --- a/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java +++ b/src/main/java/org/apache/sling/xss/impl/XSSAPIImpl.java @@ -29,16 +29,15 @@ import javax.json.JsonReaderFactory; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.Service; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.xss.ProtectionContext; import org.apache.sling.xss.XSSAPI; import org.apache.sling.xss.XSSFilter; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; import org.owasp.encoder.Encode; import org.owasp.esapi.ESAPI; import org.owasp.esapi.Validator; @@ -48,7 +47,6 @@ import org.xml.sax.InputSource; import org.xml.sax.XMLReader; @Component -@Service(value = XSSAPI.class) public class XSSAPIImpl implements XSSAPI { private static final Logger LOGGER = LoggerFactory.getLogger(XSSAPIImpl.class); @@ -64,7 +62,6 @@ public class XSSAPIImpl implements XSSAPI { private volatile JsonReaderFactory jsonReaderFactory; @Activate - @SuppressWarnings("unused") protected void activate() { factory = SAXParserFactory.newInstance(); factory.setValidating(false); @@ -82,7 +79,6 @@ public class XSSAPIImpl implements XSSAPI { } @Deactivate - @SuppressWarnings("unused") protected void deactivate() { factory = null; jsonReaderFactory = null; @@ -166,9 +162,6 @@ public class XSSAPIImpl implements XSSAPI { return defaultValue; } - private static final String LINK_PREFIX = "<a href=\""; - private static final String LINK_SUFFIX = "\"></a>"; - private static final String MANGLE_NAMESPACE_OUT_SUFFIX = ":"; private static final String MANGLE_NAMESPACE_OUT = "/([^:/]+):"; diff --git a/src/main/java/org/apache/sling/xss/impl/XSSFilterImpl.java b/src/main/java/org/apache/sling/xss/impl/XSSFilterImpl.java index ec48c9a..c5d3b8a 100644 --- a/src/main/java/org/apache/sling/xss/impl/XSSFilterImpl.java +++ b/src/main/java/org/apache/sling/xss/impl/XSSFilterImpl.java @@ -19,18 +19,13 @@ package org.apache.sling.xss.impl; import java.io.InputStream; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Properties; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.Service; +import javax.annotation.Nonnull; + import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; @@ -41,6 +36,9 @@ import org.apache.sling.api.resource.observation.ResourceChangeListener; import org.apache.sling.serviceusermapping.ServiceUserMapped; import org.apache.sling.xss.ProtectionContext; import org.apache.sling.xss.XSSFilter; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.owasp.validator.html.model.Attribute; import org.owasp.validator.html.model.Tag; import org.slf4j.Logger; @@ -50,12 +48,15 @@ import org.slf4j.LoggerFactory; * This class implements the <code>XSSFilter</code> using the Antisamy XSS protection library found at * <a href="http://code.google.com/p/owaspantisamy/">http://code.google.com/p/owaspantisamy/</a>. */ -@Component(immediate = true) -@Service(value = {ResourceChangeListener.class, XSSFilter.class}) -@Properties({ - @Property(name = ResourceChangeListener.CHANGES, value = {"ADDED", "CHANGED", "REMOVED"}), - @Property(name = ResourceChangeListener.PATHS, value = XSSFilterImpl.DEFAULT_POLICY_PATH) -}) +@Component( + service = {ResourceChangeListener.class, XSSFilter.class}, + property = { + ResourceChangeListener.CHANGES + "=ADDED", + ResourceChangeListener.CHANGES + "=CHANGED", + ResourceChangeListener.CHANGES + "=REMOVED", + ResourceChangeListener.PATHS + "=" + XSSFilterImpl.DEFAULT_POLICY_PATH + } +) public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, ExternalResourceChangeListener { private static final Logger LOGGER = LoggerFactory.getLogger(XSSFilterImpl.class); @@ -71,7 +72,7 @@ public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, Externa "removeAttribute", "" ); - public static final String DEFAULT_POLICY_PATH = "sling/xss/config.xml"; + static final String DEFAULT_POLICY_PATH = "sling/xss/config.xml"; private static final String EMBEDDED_POLICY_PATH = "SLING-INF/content/config.xml"; private static final int DEFAULT_POLICY_CACHE_SIZE = 128; private PolicyHandler defaultHandler; @@ -82,7 +83,7 @@ public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, Externa private final XSSFilterRule plainHtmlContext = new PlainTextToHtmlContentContext(); // policies cache - private Map<String, PolicyHandler> policies = new ConcurrentHashMap<String, PolicyHandler>(); + private Map<String, PolicyHandler> policies = new ConcurrentHashMap<>(); @Reference private ResourceResolverFactory resourceResolverFactory = null; @@ -91,7 +92,7 @@ public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, Externa private ServiceUserMapped serviceUserMapped; @Override - public void onChange(List<ResourceChange> resourceChanges) { + public void onChange(@Nonnull List<ResourceChange> resourceChanges) { for (ResourceChange change : resourceChanges) { if (change.getPath().endsWith(DEFAULT_POLICY_PATH)) { LOGGER.info("Detected policy file change ({}) at {}. Updating default handler.", change.getType().name(), change.getPath()); @@ -115,13 +116,75 @@ public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, Externa return this.filter(context, src, null); } + @Override + public boolean isValidHref(String url) { + // Same logic as in org.owasp.validator.html.scan.MagicSAXFilter.startElement() + boolean isValid = hrefAttribute.containsAllowedValue(url.toLowerCase()); + if (!isValid) { + isValid = hrefAttribute.matchesAllowedExpression(url); + } + return isValid; + } + @Activate - @SuppressWarnings("unused") protected void activate() { // load default handler updateDefaultHandler(); } + /* + The following methods are not part of the API. Client-code dependency to these methods is risky as they can be removed at any + point in time from the implementation. + */ + + public boolean check(final ProtectionContext context, final String src, final String policy) { + final XSSFilterRule ctx = this.getFilterRule(context); + PolicyHandler handler = null; + if (ctx.supportsPolicy()) { + if (policy == null || (handler = policies.get(policy)) == null) { + handler = defaultHandler; + } + } + return ctx.check(handler, src); + } + + public String filter(final ProtectionContext context, final String src, final String policy) { + if (src == null) { + return ""; + } + final XSSFilterRule ctx = this.getFilterRule(context); + PolicyHandler handler = null; + if (ctx.supportsPolicy()) { + if (policy == null || (handler = policies.get(policy)) == null) { + handler = defaultHandler; + } + } + return ctx.filter(handler, src); + } + + public void setDefaultPolicy(InputStream policyStream) throws Exception { + setDefaultHandler(new PolicyHandler(policyStream)); + } + + public void resetDefaultPolicy() { + updateDefaultHandler(); + } + + public void loadPolicy(String policyName, InputStream policyStream) throws Exception { + if (policies.size() < DEFAULT_POLICY_CACHE_SIZE) { + PolicyHandler policyHandler = new PolicyHandler(policyStream); + policies.put(policyName, policyHandler); + } + } + + public void unloadPolicy(String policyName) { + policies.remove(policyName); + } + + public boolean hasPolicy(String policyName) { + return policies.containsKey(policyName); + } + private synchronized void updateDefaultHandler() { this.defaultHandler = null; ResourceResolver xssResourceResolver = null; @@ -184,41 +247,6 @@ public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, Externa return this.plainHtmlContext; } - /* - The following methods are not part of the API. Client-code dependency to these methods is risky as they can be removed at any - point in time from the implementation. - */ - - public boolean check(final ProtectionContext context, final String src, final String policy) { - final XSSFilterRule ctx = this.getFilterRule(context); - PolicyHandler handler = null; - if (ctx.supportsPolicy()) { - if (policy == null || (handler = policies.get(policy)) == null) { - handler = defaultHandler; - } - } - return ctx.check(handler, src); - } - - public String filter(final ProtectionContext context, final String src, final String policy) { - if (src == null) { - return ""; - } - final XSSFilterRule ctx = this.getFilterRule(context); - PolicyHandler handler = null; - if (ctx.supportsPolicy()) { - if (policy == null || (handler = policies.get(policy)) == null) { - handler = defaultHandler; - } - } - return ctx.filter(handler, src); - } - - @SuppressWarnings("unused") - public void setDefaultPolicy(InputStream policyStream) throws Exception { - setDefaultHandler(new PolicyHandler(policyStream)); - } - private void setDefaultHandler(PolicyHandler defaultHandler) { Tag linkTag = defaultHandler.getPolicy().getTagByLowercaseName("a"); Attribute hrefAttribute = (linkTag != null) ? linkTag.getAttributeByName("href") : null; @@ -230,37 +258,4 @@ public class XSSFilterImpl implements XSSFilter, ResourceChangeListener, Externa this.defaultHandler = defaultHandler; this.hrefAttribute = hrefAttribute; } - - @SuppressWarnings("unused") - public void resetDefaultPolicy() { - updateDefaultHandler(); - } - - @SuppressWarnings("unused") - public void loadPolicy(String policyName, InputStream policyStream) throws Exception { - if (policies.size() < DEFAULT_POLICY_CACHE_SIZE) { - PolicyHandler policyHandler = new PolicyHandler(policyStream); - policies.put(policyName, policyHandler); - } - } - - @SuppressWarnings("unused") - public void unloadPolicy(String policyName) { - policies.remove(policyName); - } - - @SuppressWarnings("unused") - public boolean hasPolicy(String policyName) { - return policies.containsKey(policyName); - } - - @Override - public boolean isValidHref(String url) { - // Same logic as in org.owasp.validator.html.scan.MagicSAXFilter.startElement() - boolean isValid = hrefAttribute.containsAllowedValue(url.toLowerCase()); - if (!isValid) { - isValid = hrefAttribute.matchesAllowedExpression(url); - } - return isValid; - } } diff --git a/src/main/java/org/apache/sling/xss/package-info.java b/src/main/java/org/apache/sling/xss/package-info.java index aaec1b6..b4e3710 100644 --- a/src/main/java/org/apache/sling/xss/package-info.java +++ b/src/main/java/org/apache/sling/xss/package-info.java @@ -22,5 +22,4 @@ @Version("2.0.0") package org.apache.sling.xss; -import aQute.bnd.annotation.Version; - +import org.osgi.annotation.versioning.Version; -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
