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 af95a37df..a0c048a46 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,23 @@ public class SecurityMemberAccess implements MemberAccess { private final ProviderAllowlist providerAllowlist; private final ThreadAllowlist threadAllowlist; + private boolean allowStaticFieldAccess = true; + private Set excludeProperties = emptySet(); private Set acceptProperties = emptySet(); + private Set excludedClasses = unmodifiableSet(new HashSet<>(singletonList(Object.class.getName()))); private Set excludedPackageNamePatterns = emptySet(); private Set excludedPackageNames = emptySet(); private Set excludedPackageExemptClasses = emptySet(); + + private boolean isDevMode; + private boolean enforceAllowlistEnabled = false; private Set> allowlistClasses = emptySet(); private Set allowlistPackageNames = emptySet(); + private boolean disallowProxyObjectAccess = false; private boolean disallowProxyMemberAccess = false; private boolean disallowDefaultPackageAccess = false; @@ -220,6 +227,7 @@ public class SecurityMemberAccess implements MemberAccess { // entities. This is preferred to having to disable the allowlist capability entirely. Object newTarget = ProxyUtil.getHibernateProxyTarget(target); if (newTarget != target) { + logAllowlistHibernateEntity(target, newTarget); target = newTarget; member = ProxyUtil.resolveTargetMember(member, newTarget); } @@ -241,6 +249,21 @@ public class SecurityMemberAccess implements MemberAccess { return true; } + private void logAllowlistHibernateEntity(Object original, Object resolved) { + if (!isDevMode && !LOG.isDebugEnabled()) { + return; + } + String msg = "Hibernate entity [{}] resolved to [{}] for purpose of OGNL allowlisting." + + " We don't recommend executing OGNL expressions against Hibernate entities, you may disallow this behaviour using the configuration `{}=true`."; + Object[] args = {original, resolved, StrutsConstants.STRUTS_DISALLOW_PROXY_OBJECT_ACCESS}; + if (isDevMode) { + LOG.warn(msg, args); + } else { + LOG.debug(msg, args); + } + + } + protected boolean isClassAllowlisted(Class clazz) { return allowlistClasses.contains(clazz) || ALLOWLIST_REQUIRED_CLASSES.contains(clazz) @@ -473,4 +496,9 @@ public class SecurityMemberAccess implements MemberAccess { public void useDisallowDefaultPackageAccess(String disallowDefaultPackageAccess) { this.disallowDefaultPackageAccess = BooleanUtils.toBoolean(disallowDefaultPackageAccess); } + + @Inject(StrutsConstants.STRUTS_DEVMODE) + protected void useDevMode(String devMode) { + this.isDevMode = BooleanUtils.toBoolean(devMode); + } }