Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WW-5343 Make SecurityMemberAccess an extensible bean #791

Merged
merged 20 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
79ffc86
WW-5343 Delete unused code and consolidate constructors
kusalk Aug 31, 2023
0825329
WW-5343 Extract ConfigParseUtil
kusalk Nov 14, 2023
b0b80ba
WW-5343 Extract deprecated methods as default interface methods
kusalk Nov 14, 2023
9e556e9
WW-5343 Deprecate unnecessary setter
kusalk Nov 14, 2023
90344b3
WW-5343 Make SecurityMemberAccess a prototype bean
kusalk Nov 14, 2023
7e92a8d
WW-5343 Refactor OgnlValueStackFactory to utilise SecurityMemberAcces…
kusalk Nov 14, 2023
b518635
WW-5343 Update OgnlUtil#createDefaultContext to utilise SecurityMembe…
kusalk Nov 14, 2023
4490d9d
WW-5343 Move configuration injection from OgnlUtil to SecurityMemberA…
kusalk Nov 14, 2023
8bf47b3
WW-5343 Fix OgnlUtilTest#testBeanMapExpressions
kusalk Nov 14, 2023
62988f7
WW-5343 Fix unit test compilation errors
kusalk Nov 14, 2023
ceff6cd
WW-5343 Remove unnecessary method
kusalk Nov 16, 2023
f87d7d7
WW-5343 Add missing license
kusalk Nov 17, 2023
a402e5c
WW-5343 Revert and fix serializability
kusalk Nov 17, 2023
d0d10d9
WW-5343 Fix MemberAccess access blocked tests
kusalk Nov 17, 2023
68f5584
WW-5343 Remove defunct test now that constant is required
kusalk Nov 17, 2023
05a9973
Merge branch 'master' into WW-5343-sec-extend
kusalk Nov 17, 2023
9640f5b
WW-5343 Migrate tests to SecurityMemberAccessTest
kusalk Nov 22, 2023
eba79a7
WW-5343 Fix final test
kusalk Nov 22, 2023
85d2c74
WW-5343 Clean up bootstrap constants
kusalk Nov 26, 2023
7929d86
WW-5343 Address SonarCloud code smells
kusalk Nov 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import com.opensymphony.xwork2.ognl.OgnlReflectionProvider;
import com.opensymphony.xwork2.ognl.OgnlUtil;
import com.opensymphony.xwork2.ognl.OgnlValueStackFactory;
import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.OgnlTextParser;
Expand Down Expand Up @@ -132,16 +133,13 @@ public class DefaultConfiguration implements Configuration {
static {
Map<String, Object> constants = new HashMap<>();
constants.put(StrutsConstants.STRUTS_DEVMODE, Boolean.FALSE);
constants.put(StrutsConstants.STRUTS_OGNL_LOG_MISSING_PROPERTIES, Boolean.FALSE);
constants.put(StrutsConstants.STRUTS_OGNL_ENABLE_EVAL_EXPRESSION, Boolean.FALSE);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constant is not required for bootstrapping

constants.put(StrutsConstants.STRUTS_OGNL_ENABLE_EXPRESSION_CACHE, Boolean.TRUE);
constants.put(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, Boolean.FALSE);
constants.put(StrutsConstants.STRUTS_I18N_RELOAD, Boolean.FALSE);
constants.put(StrutsConstants.STRUTS_MATCHER_APPEND_NAMED_PARAMETERS, Boolean.TRUE);
constants.put(StrutsConstants.STRUTS_OGNL_EXPRESSION_CACHE_TYPE, OgnlCacheFactory.CacheType.BASIC);
constants.put(StrutsConstants.STRUTS_OGNL_EXPRESSION_CACHE_MAXSIZE, 10000);
constants.put(StrutsConstants.STRUTS_OGNL_BEANINFO_CACHE_TYPE, OgnlCacheFactory.CacheType.BASIC);
constants.put(StrutsConstants.STRUTS_OGNL_BEANINFO_CACHE_MAXSIZE, 10000);
constants.put(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, Boolean.FALSE);
BOOTSTRAP_CONSTANTS = Collections.unmodifiableMap(constants);
}

Expand Down Expand Up @@ -385,6 +383,7 @@ protected Container createBootstrapContainer(List<ContainerProvider> providers)
builder.factory(ExpressionCacheFactory.class, DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON);
builder.factory(BeanInfoCacheFactory.class, DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON);
builder.factory(OgnlUtil.class, Scope.SINGLETON);
builder.factory(SecurityMemberAccess.class, Scope.PROTOTYPE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is a good idea, attacker could get access to the SMA just by having access to the Container

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given it's prototype scope, I don't believe it to make any difference

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is, the container would return a new instance, and not the one that is being used by the ValueStack

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant it will be possible creating a new instance via containers methods, yet we excluded the whole package com.opensymphony.xwork2.inject which means attacker cannot use container in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I also don't think there's anything useful an attacker can do with a fresh SecurityMemberAccess instance

builder.factory(OgnlGuard.class, StrutsOgnlGuard.class, Scope.SINGLETON);

builder.factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.opensymphony.xwork2.inject.ContainerBuilder;
import com.opensymphony.xwork2.inject.Scope;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import org.apache.struts2.StrutsConstants;

import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -62,7 +61,6 @@ public void selfRegister() {
for (Map.Entry<String, Object> entry : DefaultConfiguration.BOOTSTRAP_CONSTANTS.entrySet()) {
builder.constant(entry.getKey(), String.valueOf(entry.getValue()));
}
builder.constant(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, "false");
container = builder.create(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import com.opensymphony.xwork2.ognl.OgnlReflectionProvider;
import com.opensymphony.xwork2.ognl.OgnlUtil;
import com.opensymphony.xwork2.ognl.OgnlValueStackFactory;
import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
import com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor;
import com.opensymphony.xwork2.ognl.accessor.ObjectAccessor;
Expand Down Expand Up @@ -113,7 +114,6 @@
import com.opensymphony.xwork2.validator.ValidatorFileParser;
import ognl.MethodAccessor;
import ognl.PropertyAccessor;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.conversion.StrutsConversionPropertiesProcessor;
import org.apache.struts2.conversion.StrutsTypeConverterCreator;
import org.apache.struts2.conversion.StrutsTypeConverterHolder;
Expand Down Expand Up @@ -230,6 +230,7 @@ public void register(ContainerBuilder builder, LocatableProperties props)
.factory(ExpressionCacheFactory.class, DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON)
.factory(BeanInfoCacheFactory.class, DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON)
.factory(OgnlUtil.class, Scope.SINGLETON)
.factory(SecurityMemberAccess.class, Scope.PROTOTYPE)
.factory(OgnlGuard.class, StrutsOgnlGuard.class, Scope.SINGLETON)
.factory(CollectionConverter.class, Scope.SINGLETON)
.factory(ArrayConverter.class, Scope.SINGLETON)
Expand All @@ -255,8 +256,5 @@ public void register(ContainerBuilder builder, LocatableProperties props)
for (Map.Entry<String, Object> entry : DefaultConfiguration.BOOTSTRAP_CONSTANTS.entrySet()) {
props.setProperty(entry.getKey(), String.valueOf(entry.getValue()));
}

props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS, Boolean.TRUE.toString());
props.setProperty(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, Boolean.FALSE.toString());
}
}
Loading