This is an automated email from the ASF dual-hosted git repository.
joerghoh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-xss.git
The following commit(s) were added to refs/heads/master by this push:
new 2991c35 Sanitizer policy reload failure could leave sanitizer in a
degraded state
2991c35 is described below
commit 2991c35f654814ce216cb3f07078e4dedda07166
Author: Joerg Hoh <[email protected]>
AuthorDate: Mon Sep 14 18:26:10 2026 +0200
Sanitizer policy reload failure could leave sanitizer in a degraded state
---
.../org/apache/sling/xss/impl/XSSFilterImpl.java | 28 +++++++++++++++-------
.../apache/sling/xss/impl/XSSFilterImplTest.java | 24 +++++++++++++++++++
2 files changed, 44 insertions(+), 8 deletions(-)
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 9e00c2b..dd31b6d 100644
--- a/src/main/java/org/apache/sling/xss/impl/XSSFilterImpl.java
+++ b/src/main/java/org/apache/sling/xss/impl/XSSFilterImpl.java
@@ -558,16 +558,28 @@ public class XSSFilterImpl implements XSSFilter {
synchronized void updateActivePolicy() {
final AntiSamyPolicy originalActivePolicy = this.activePolicy;
- this.activePolicy = withPolicyResource(AntiSamyPolicy::create);
- // the originalActivePolicy can only be null during the first
activation
- if (activePolicy == null && originalActivePolicy == null) {
- // the content-based policy file is not (yet) available, fall back
to the embedded policy
- this.activePolicy = AntiSamyPolicy.createEmbedded();
- if (activePolicy == null) {
- throw new IllegalStateException("Cannot load a policy
handler.");
+ AntiSamyPolicy newActivePolicy =
withPolicyResource(AntiSamyPolicy::create);
+ if (newActivePolicy == null) {
+ // the content-based policy file is not (or no longer) available
or failed to load, fall
+ // back to the embedded policy.
+ if (originalActivePolicy != null &&
!originalActivePolicy.isEmbedded()) {
+ logger.error("Unable to load a policy from {}. Falling back to
the embedded policy file.", policyPath);
+ }
+ newActivePolicy = AntiSamyPolicy.createEmbedded();
+ if (newActivePolicy == null) {
+ if (originalActivePolicy != null) {
+ logger.error(
+ "Unable to load the embedded policy file either.
Keeping the previously active policy from {}.",
+ originalActivePolicy.getPath());
+ return;
+ } else {
+ throw new IllegalStateException(
+ "Cannot load neither embedded policy nor policy
file at '" + policyPath + "'");
+ }
}
}
- updatePolicyHandler(activePolicy.getPolicyHandler());
+ this.activePolicy = newActivePolicy;
+ updatePolicyHandler(newActivePolicy.getPolicyHandler());
}
private <T> T withPolicyResource(Function<Resource, T> mapper) {
diff --git a/src/test/java/org/apache/sling/xss/impl/XSSFilterImplTest.java
b/src/test/java/org/apache/sling/xss/impl/XSSFilterImplTest.java
index 5791839..640a1d0 100644
--- a/src/test/java/org/apache/sling/xss/impl/XSSFilterImplTest.java
+++ b/src/test/java/org/apache/sling/xss/impl/XSSFilterImplTest.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.external.URIProvider;
import org.apache.sling.commons.metrics.Counter;
@@ -159,6 +160,29 @@ public class XSSFilterImplTest {
testResourceBasedPolicy();
}
+ @Test
+ public void testPolicyRemovalFallsBackToEmbeddedPolicy() throws
PersistenceException {
+ String policyPath = "/libs/" + XSSFilterImpl.DEFAULT_POLICY_PATH;
+ context.load().binaryFile(getPolicyFileAsStream(), policyPath);
+ // re-register in order to pick up the newly uploaded policy
+ xssFilter = context.registerInjectActivateService(new XSSFilterImpl());
+ assertFalse(xssFilter.getActivePolicy().isEmbedded(), "Expected a
Resource based policy.");
+
+ Resource policyResource =
context.resourceResolver().getResource(policyPath);
+ context.resourceResolver().delete(policyResource);
+ context.resourceResolver().commit();
+
+ // simulate the resource change event delivered when the policy
resource is removed; this
+ // must never leave the filter without a working policy
+ xssFilter.updateActivePolicy();
+
+ XSSFilterImpl.AntiSamyPolicy antiSamyPolicy =
xssFilter.getActivePolicy();
+ assertTrue(antiSamyPolicy.isEmbedded(), "Expected a fallback to the
embedded policy.");
+ assertTrue(
+ xssFilter.check(XSSFilter.DEFAULT_CONTEXT, "<p>some text</p>"),
+ "Expected the filter to keep working after the policy resource
was removed.");
+ }
+
@Test
public void testDefaultEmbeddedPolicy() {
XSSFilterImpl.AntiSamyPolicy antiSamyPolicy =
xssFilter.getActivePolicy();