Merge remote-tracking branch 'origin/master' into merge/master-to-7xx-2024-10-15

# Conflicts:
#	core/src/main/java/org/apache/struts2/components/UIBean.java
#	plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AbstractTest.java
#	pom.xml
This commit is contained in:
Lukasz Lenart
2024-10-15 07:19:00 +02:00
10 changed files with 71 additions and 47 deletions
+3 -3
View File
@@ -52,12 +52,12 @@ jobs:
java-version: 17
cache: 'maven'
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.26.6
uses: github/codeql-action/init@v3.26.12
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3.26.6
uses: github/codeql-action/autobuild@v3.26.12
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.26.6
uses: github/codeql-action/analyze@v3.26.12
with:
category: "/language:${{matrix.language}}"
+2 -2
View File
@@ -58,13 +58,13 @@ jobs:
publish_results: true
- name: "Upload artifact"
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # 4.4.0
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # 4.4.3
with:
name: SARIF file
path: results.sarif
retention-days: 5
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@821ab42c90a42d1d5cd3241930dff56a7c7dcfb2 # 2.22.11
uses: github/codeql-action/upload-sarif@ea2cd92c21b192add69983116b8b3222b09da33b # 2.22.11
with:
sarif_file: results.sarif
@@ -24,6 +24,7 @@ import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
@@ -863,10 +864,13 @@ public abstract class UIBean extends Component {
}
// to be used with the CSP interceptor - adds the nonce value as a parameter to be accessed from ftl files
Map<String, Object> session = stack.getActionContext().getSession();
Object nonceValue = session != null ? session.get("nonce") : null;
HttpSession session = stack.getActionContext().getServletRequest().getSession(false);
Object nonceValue = session != null ? session.getAttribute("nonce") : null;
if (nonceValue != null) {
addParameter("nonce", nonceValue.toString());
} else {
LOG.debug("Session is not active, cannot obtain nonce value");
}
evaluateExtraParams();
@@ -25,12 +25,13 @@ import org.apache.struts2.StrutsInternalTestCase;
import org.apache.struts2.components.template.Template;
import org.apache.struts2.components.template.TemplateEngine;
import org.apache.struts2.components.template.TemplateEngineManager;
import org.apache.struts2.dispatcher.SessionMap;
import org.apache.struts2.dispatcher.StaticContentLoader;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsCheckerTest.NO_EXCLUSION_ACCEPT_ALL_PATTERNS_CHECKER;
@@ -160,7 +161,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
try {
txtFld.mergeTemplate(null, new Template(null, null, null));
fail("Exception not thrown");
} catch(final Exception e){
} catch (final Exception e) {
assertTrue(e instanceof ConfigurationException);
}
}
@@ -225,6 +226,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
TextField txtFld = new TextField(stack, req, res);
txtFld.setAccesskey(accesskeyValue);
@@ -238,6 +240,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
TextField txtFld = new TextField(stack, req, res);
txtFld.addParameter("value", value);
@@ -250,11 +253,13 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
stack.push(new Object() {
public String getMyValue() {
return "%{myBad}";
}
public String getMyBad() {
throw new IllegalStateException("Recursion detected!");
}
@@ -273,11 +278,13 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
stack.push(new Object() {
public String getMyValueName() {
return "getMyValue()";
}
public String getMyValue() {
return "value";
}
@@ -300,6 +307,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
stack.push(new Object() {
public String getMyValue() {
@@ -320,6 +328,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
TextField txtFld = new TextField(stack, req, res);
txtFld.setCssClass(cssClass);
@@ -333,6 +342,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext.getContext().withServletRequest(req);
TextField txtFld = new TextField(stack, req, res);
txtFld.setStyle(cssStyle);
@@ -347,9 +357,12 @@ public class UIBeanTest extends StrutsInternalTestCase {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext actionContext = stack.getActionContext();
Map<String, Object> session = new HashMap<>();
session.put("nonce", nonceVal);
actionContext.withSession(session);
actionContext.withServletRequest(req);
MockHttpSession session = new MockHttpSession();
session.setAttribute("nonce", nonceVal);
req.setSession(session);
actionContext.withSession(new SessionMap(req));
DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
dblSelect.evaluateParams();
@@ -357,6 +370,26 @@ public class UIBeanTest extends StrutsInternalTestCase {
assertEquals(nonceVal, dblSelect.getParameters().get("nonce"));
}
public void testNonceOfInvalidSession() {
String nonceVal = "r4nd0m";
ValueStack stack = ActionContext.getContext().getValueStack();
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
ActionContext actionContext = stack.getActionContext();
actionContext.withServletRequest(req);
MockHttpSession session = new MockHttpSession();
session.setAttribute("nonce", nonceVal);
req.setSession(session);
actionContext.withSession(new SessionMap(req));
session.invalidate();
DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
dblSelect.evaluateParams();
assertNull(dblSelect.getParameters().get("nonce"));
}
public void testSetNullUiStaticContentPath() {
// given
ValueStack stack = ActionContext.getContext().getValueStack();
@@ -27,6 +27,7 @@ import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.OgnlTextParser;
import com.opensymphony.xwork2.util.TextParser;
import com.opensymphony.xwork2.util.ValueStack;
import jakarta.servlet.http.HttpSession;
import junit.framework.TestCase;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.UIBean;
@@ -51,6 +52,8 @@ public abstract class AbstractTest extends TestCase {
private final Map<String, String> commonAttrs = new HashMap<>();
private final Map<String, String> dynamicAttrs = new HashMap<>();
protected static final String NONCE_VAL = "r4andom";
protected SimpleTheme theme;
protected StringWriter writer;
@@ -62,6 +65,7 @@ public abstract class AbstractTest extends TestCase {
protected TemplateRenderingContext context;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession session;
protected abstract UIBean getUIBean() throws Exception;
@@ -107,6 +111,12 @@ public abstract class AbstractTest extends TestCase {
expect(request.getContextPath()).andReturn("/some/path").anyTimes();
response = createNiceMock(HttpServletResponse.class);
session = createNiceMock(HttpSession.class);
expect(session.getAttribute("nonce")).andReturn(NONCE_VAL).anyTimes();
expect(request.getSession(false)).andReturn(session).anyTimes();
actionContext.withServletRequest(request);
expect(stack.getActionContext()).andReturn(actionContext).anyTimes();
expect(stack.getContext()).andReturn(stackContext).anyTimes();
@@ -116,6 +126,7 @@ public abstract class AbstractTest extends TestCase {
TextParser parser = new OgnlTextParser();
expect(container.getInstance(TextParser.class)).andReturn(parser).anyTimes();
replay(session);
replay(request);
replay(stack);
replay(container);
@@ -31,7 +31,7 @@ public class HeadTest extends AbstractTest {
map.putAll(tag.getParameters());
theme.renderTag(getTagName(), context);
String output = writer.getBuffer().toString();
String expected = s("<script type='text/javascript' base='/some/path' src='/some/path/static/utils.js'></script>");
String expected = s("<script type='text/javascript' base='/some/path' src='/some/path/static/utils.js' nonce='r4andom'></script>");
assertEquals(expected, output);
}
@@ -18,19 +18,13 @@
*/
package org.apache.struts2.views.java.simple;
import com.opensymphony.xwork2.ActionContext;
import org.apache.struts2.components.Link;
import org.apache.struts2.components.UIBean;
import java.util.HashMap;
import java.util.Map;
public class LinkTest extends AbstractTest{
public class LinkTest extends AbstractTest {
private Link tag;
private static final String NONCE_VAL = "r4andom";
public void testRenderLinkTag() {
tag.setHref("testhref");
tag.setHreflang("test");
@@ -60,7 +54,7 @@ public class LinkTest extends AbstractTest{
assertTrue("Incorrect as attribute for link tag", output.contains(s("as='test'")));
assertFalse("Non-existent disabled attribute for link tag", output.contains(s("disabled='disabled'")));
assertTrue("Incorrect title attribute for link tag", output.contains(s("title='test'")));
assertTrue("Incorrect nonce attribute for link tag", output.contains(s("nonce='" + NONCE_VAL+"'")));
assertTrue("Incorrect nonce attribute for link tag", output.contains(s("nonce='" + NONCE_VAL + "'")));
}
public void testRenderLinkTagAsStylesheet() {
@@ -92,7 +86,7 @@ public class LinkTest extends AbstractTest{
assertTrue("Incorrect as attribute for link tag", output.contains(s("as='test'")));
assertTrue("Incorrect disabled attribute for link tag", output.contains(s("disabled='disabled'")));
assertTrue("Incorrect title attribute for link tag", output.contains(s("title='test'")));
assertTrue("Incorrect nonce attribute for link tag", output.contains(s("nonce='" + NONCE_VAL+"'")));
assertTrue("Incorrect nonce attribute for link tag", output.contains(s("nonce='" + NONCE_VAL + "'")));
}
@Override
@@ -108,12 +102,6 @@ public class LinkTest extends AbstractTest{
@Override
protected void setUp() throws Exception {
super.setUp();
ActionContext actionContext = stack.getActionContext();
Map<String, Object> session = new HashMap<>();
session.put("nonce", NONCE_VAL);
actionContext.withSession(session);
this.tag = new Link(stack, request, response);
}
}
@@ -18,22 +18,15 @@
*/
package org.apache.struts2.views.java.simple;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsChecker;
import org.apache.struts2.components.Script;
import org.apache.struts2.components.UIBean;
import java.util.HashMap;
import java.util.Map;
public class ScriptTest extends AbstractTest {
private Script tag;
private static final String NONCE_VAL = "r4andom";
public void testRenderScriptTag() {
tag.setName("name_");
tag.setType("text/javascript");
@@ -77,11 +70,6 @@ public class ScriptTest extends AbstractTest {
protected void setUp() throws Exception {
super.setUp();
ActionContext actionContext = stack.getActionContext();
Map<String, Object> session = new HashMap<>();
session.put("nonce", NONCE_VAL);
actionContext.withSession(session);
this.tag = new Script(stack, request, response);
tag.setNotExcludedAcceptedPatterns(new DefaultNotExcludedAcceptedPatternsChecker());
}
+1 -1
View File
@@ -40,7 +40,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<executions>
<execution>
<phase>compile</phase>
+6 -6
View File
@@ -114,8 +114,8 @@
<byte-buddy.version>1.14.11</byte-buddy.version>
<freemarker.version>2.3.33</freemarker.version>
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
<jackson.version>2.17.2</jackson.version>
<log4j2.version>2.23.1</log4j2.version>
<jackson.version>2.18.0</jackson.version>
<log4j2.version>2.24.1</log4j2.version>
<maven-surefire-plugin.version>3.5.0</maven-surefire-plugin.version>
<mockito.version>5.8.0</mockito.version>
<ognl.version>3.3.5</ognl.version>
@@ -240,7 +240,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.6.2</version>
<version>3.7.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -332,7 +332,7 @@
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>10.0.3</version>
<version>10.0.4</version>
<configuration>
<suppressionFiles>
<suppressionFile>src/etc/project-suppression.xml</suppressionFile>
@@ -405,7 +405,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
<version>3.20.0</version>
<configuration>
<relativizeDecorationLinks>false</relativizeDecorationLinks>
</configuration>
@@ -797,7 +797,7 @@
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.3</version>
<version>1.3.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>