You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by ku...@apache.org on 2024/07/08 08:42:16 UTC
(struts) 01/01: WW-5439 Move Dev Mode security configuration
This is an automated email from the ASF dual-hosted git repository.
kusal pushed a commit to branch WW-5439-fix-dev-mode
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 6e07b01b65e5067c311ad5eed24e5a1f0524850d
Author: Kusal Kithul-Godage <gi...@kusal.io>
AuthorDate: Mon Jul 8 18:42:06 2024 +1000
WW-5439 Move Dev Mode security configuration
---
.../com/opensymphony/xwork2/ognl/OgnlUtil.java | 54 +++++++++++-----------
.../xwork2/ognl/SecurityMemberAccess.java | 50 ++++++++++++++++++++
2 files changed, 76 insertions(+), 28 deletions(-)
diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
index 681aac57d..1fee7a257 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
@@ -47,7 +47,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import static com.opensymphony.xwork2.util.ConfigParseUtil.toClassesSet;
@@ -68,9 +67,6 @@ public class OgnlUtil {
private static final Logger LOG = LogManager.getLogger(OgnlUtil.class);
- // Flag used to reduce flooding logs with WARNs about using DevMode excluded packages
- private final AtomicBoolean warnReported = new AtomicBoolean(false);
-
private final OgnlCache<String, Object> expressionCache;
private final OgnlCache<Class<?>, BeanInfo> beanInfoCache;
private TypeConverter defaultConverter;
@@ -80,11 +76,6 @@ public class OgnlUtil {
private boolean enableExpressionCache = true;
private boolean enableEvalExpression;
- private String devModeExcludedClasses = "";
- private String devModeExcludedPackageNamePatterns = "";
- private String devModeExcludedPackageNames = "";
- private String devModeExcludedPackageExemptClasses = "";
-
private Container container;
/**
@@ -124,6 +115,7 @@ public class OgnlUtil {
@Inject(StrutsConstants.STRUTS_DEVMODE)
protected void setDevMode(String mode) {
this.devMode = BooleanUtils.toBoolean(mode);
+ LOG.warn("Working in devMode, using devMode excluded classes and packages!");
}
@Inject(value = StrutsConstants.STRUTS_OGNL_ENABLE_EXPRESSION_CACHE, required = false)
@@ -164,9 +156,12 @@ public class OgnlUtil {
// Must be set directly on SecurityMemberAccess
}
- @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_CLASSES, required = false)
+ /**
+ * @deprecated since 6.5.0, no replacement.
+ */
+ @Deprecated
protected void setDevModeExcludedClasses(String commaDelimitedClasses) {
- this.devModeExcludedClasses = commaDelimitedClasses;
+ // Must be set directly on SecurityMemberAccess
}
/**
@@ -177,9 +172,12 @@ public class OgnlUtil {
// Must be set directly on SecurityMemberAccess
}
- @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_PACKAGE_NAME_PATTERNS, required = false)
+ /**
+ * @deprecated since 6.5.0, no replacement.
+ */
+ @Deprecated
protected void setDevModeExcludedPackageNamePatterns(String commaDelimitedPackagePatterns) {
- this.devModeExcludedPackageNamePatterns = commaDelimitedPackagePatterns;
+ // Must be set directly on SecurityMemberAccess
}
/**
@@ -190,9 +188,12 @@ public class OgnlUtil {
// Must be set directly on SecurityMemberAccess
}
- @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_PACKAGE_NAMES, required = false)
+ /**
+ * @deprecated since 6.5.0, no replacement.
+ */
+ @Deprecated
protected void setDevModeExcludedPackageNames(String commaDelimitedPackageNames) {
- this.devModeExcludedPackageNames = commaDelimitedPackageNames;
+ // Must be set directly on SecurityMemberAccess
}
/**
@@ -203,9 +204,12 @@ public class OgnlUtil {
// Must be set directly on SecurityMemberAccess
}
- @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_PACKAGE_EXEMPT_CLASSES, required = false)
+ /**
+ * @deprecated since 6.5.0, no replacement.
+ */
+ @Deprecated
public void setDevModeExcludedPackageExemptClasses(String commaDelimitedClasses) {
- this.devModeExcludedPackageExemptClasses = commaDelimitedClasses;
+ // Must be set directly on SecurityMemberAccess
}
/**
@@ -856,6 +860,11 @@ public class OgnlUtil {
return createDefaultContext(root, null);
}
+ /**
+ * Note that the allowlist capability is not enforced by the {@link OgnlContext} returned by this method. Currently,
+ * this context is only leveraged by some public methods on {@link OgnlUtil} which are called by
+ * {@link OgnlReflectionProvider}.
+ */
protected Map<String, Object> createDefaultContext(Object root, ClassResolver resolver) {
if (resolver == null) {
resolver = container.getInstance(RootAccessor.class);
@@ -867,17 +876,6 @@ public class OgnlUtil {
SecurityMemberAccess memberAccess = container.getInstance(SecurityMemberAccess.class);
memberAccess.useEnforceAllowlistEnabled(Boolean.FALSE.toString());
- if (devMode) {
- if (!warnReported.get()) {
- warnReported.set(true);
- LOG.warn("Working in devMode, using devMode excluded classes and packages!");
- }
- memberAccess.useExcludedClasses(devModeExcludedClasses);
- memberAccess.useExcludedPackageNamePatterns(devModeExcludedPackageNamePatterns);
- memberAccess.useExcludedPackageNames(devModeExcludedPackageNames);
- memberAccess.useExcludedPackageExemptClasses(devModeExcludedPackageExemptClasses);
- }
-
return Ognl.createDefaultContext(root, memberAccess, resolver, defaultConverter);
}
diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
index f882b2c58..f2eab0c3e 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java
@@ -77,16 +77,27 @@ public class SecurityMemberAccess implements MemberAccess {
private final ProviderAllowlist providerAllowlist;
private final ThreadAllowlist threadAllowlist;
+
private boolean allowStaticFieldAccess = true;
+
private Set<Pattern> excludeProperties = emptySet();
private Set<Pattern> acceptProperties = emptySet();
+
private Set<String> excludedClasses = unmodifiableSet(new HashSet<>(singletonList(Object.class.getName())));
private Set<Pattern> excludedPackageNamePatterns = emptySet();
private Set<String> excludedPackageNames = emptySet();
private Set<String> excludedPackageExemptClasses = emptySet();
+
+ private boolean devMode;
+ private Set<String> devModeExcludedClasses = unmodifiableSet(new HashSet<>(singletonList(Object.class.getName())));
+ private Set<Pattern> devModeExcludedPackageNamePatterns = emptySet();
+ private Set<String> devModeExcludedPackageNames = emptySet();
+ private Set<String> devModeExcludedPackageExemptClasses = emptySet();
+
private boolean enforceAllowlistEnabled = false;
private Set<Class<?>> allowlistClasses = emptySet();
private Set<String> allowlistPackageNames = emptySet();
+
private boolean disallowProxyObjectAccess = false;
private boolean disallowProxyMemberAccess = false;
private boolean disallowDefaultPackageAccess = false;
@@ -460,4 +471,43 @@ public class SecurityMemberAccess implements MemberAccess {
public void useDisallowDefaultPackageAccess(String disallowDefaultPackageAccess) {
this.disallowDefaultPackageAccess = BooleanUtils.toBoolean(disallowDefaultPackageAccess);
}
+
+ @Inject(StrutsConstants.STRUTS_DEVMODE)
+ protected void setDevMode(String devMode) {
+ this.devMode = BooleanUtils.toBoolean(devMode);
+ setDevModeConfiguration();
+ }
+
+ @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_CLASSES, required = false)
+ public void useDevModeExcludedClasses(String commaDelimitedClasses) {
+ this.devModeExcludedClasses = toNewClassesSet(devModeExcludedClasses, commaDelimitedClasses);
+ setDevModeConfiguration();
+ }
+
+ @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_PACKAGE_NAME_PATTERNS, required = false)
+ public void useDevModeExcludedPackageNamePatterns(String commaDelimitedPackagePatterns) {
+ this.devModeExcludedPackageNamePatterns = toNewPatternsSet(devModeExcludedPackageNamePatterns, commaDelimitedPackagePatterns);
+ setDevModeConfiguration();
+ }
+
+ @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_PACKAGE_NAMES, required = false)
+ public void useDevModeExcludedPackageNames(String commaDelimitedPackageNames) {
+ this.devModeExcludedPackageNames = toNewPackageNamesSet(devModeExcludedPackageNames, commaDelimitedPackageNames);
+ setDevModeConfiguration();
+ }
+
+ @Inject(value = StrutsConstants.STRUTS_DEV_MODE_EXCLUDED_PACKAGE_EXEMPT_CLASSES, required = false)
+ public void useDevModeExcludedPackageExemptClasses(String commaDelimitedClasses) {
+ this.devModeExcludedPackageExemptClasses = toClassesSet(commaDelimitedClasses);
+ setDevModeConfiguration();
+ }
+
+ private void setDevModeConfiguration() {
+ if (this.devMode) {
+ excludedClasses = devModeExcludedClasses;
+ excludedPackageNamePatterns = devModeExcludedPackageNamePatterns;
+ excludedPackageNames = devModeExcludedPackageNames;
+ excludedPackageExemptClasses = devModeExcludedPackageExemptClasses;
+ }
+ }
}