Medium severity6.1NVD Advisory· Published Apr 12, 2016· Updated May 6, 2026
CVE-2016-2162
CVE-2016-2162
Description
Apache Struts 2.x before 2.3.25 does not sanitize text in the Locale object constructed by I18NInterceptor, which might allow remote attackers to conduct cross-site scripting (XSS) attacks via unspecified vectors involving language display.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.struts:struts2-coreMaven | >= 2.0.0, < 2.3.28 | 2.3.28 |
Affected products
57cpe:2.3:a:apache:struts:2.0.0:*:*:*:*:*:*:*+ 55 more
- cpe:2.3:a:apache:struts:2.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.10:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.11:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.11.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.11.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.12:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.13:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.14:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.5:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.6:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.7:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.8:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.0.9:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.2_beta:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.4:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.5:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.6:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.8:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.1.8.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.2.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.2.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.2.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.2.3.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.1.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.12:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.14:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.14.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.14.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.14.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.15:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.15.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.15.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.15.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.16:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.16.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.16.2:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.16.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.20:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.24:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.24.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.3:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.4:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.4.1:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.7:*:*:*:*:*:*:*
- cpe:2.3:a:apache:struts:2.3.8:*:*:*:*:*:*:*
Patches
1fc2179cf1ac9Narrows possible locale to those from available locales
3 files changed · +21 −16
core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java+5 −0 modified@@ -21,6 +21,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.Arrays; import java.util.Locale; import java.util.Map; @@ -218,6 +219,10 @@ protected Locale getLocaleFromParam(Object requestedLocale) { LOG.debug("Applied request locale: {}", locale); } } + + if (locale != null && !Arrays.asList(Locale.getAvailableLocales()).contains(locale)) { + locale = Locale.getDefault(); + } return locale; }
core/src/test/java/com/opensymphony/xwork2/interceptor/I18nInterceptorTest.java+8 −8 modified@@ -82,12 +82,12 @@ public void testDenmarkLocaleRequestOnly() throws Exception { } public void testCountryOnlyLocale() throws Exception { - params.put(I18nInterceptor.DEFAULT_PARAMETER, "DK"); + params.put(I18nInterceptor.DEFAULT_PARAMETER, "NL"); interceptor.intercept(mai); assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed - Locale denmark = new Locale("DK"); + Locale denmark = new Locale("NL"); assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here assertEquals(denmark, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object } @@ -104,30 +104,30 @@ public void testLanguageOnlyLocale() throws Exception { } public void testWithVariant() throws Exception { - params.put(I18nInterceptor.DEFAULT_PARAMETER, "fr_CA_xx"); + params.put(I18nInterceptor.DEFAULT_PARAMETER, "ja_JP_JP"); interceptor.intercept(mai); assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed - Locale variant = new Locale("fr", "CA", "xx"); + Locale variant = new Locale("ja", "JP", "JP"); Locale locale = (Locale) session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE); assertNotNull(locale); // should be stored here assertEquals(variant, locale); - assertEquals("xx", locale.getVariant()); + assertEquals("JP", locale.getVariant()); } public void testWithVariantRequestOnly() throws Exception { - params.put(I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER, "fr_CA_xx"); + params.put(I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER, "ja_JP_JP"); interceptor.intercept(mai); assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed assertNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); - Locale variant = new Locale("fr", "CA", "xx"); + Locale variant = new Locale("ja", "JP", "JP"); Locale locale = mai.getInvocationContext().getLocale(); assertNotNull(locale); // should be stored here assertEquals(variant, locale); - assertEquals("xx", locale.getVariant()); + assertEquals("JP", locale.getVariant()); } public void testRealLocaleObjectInParams() throws Exception {
core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java+8 −8 modified@@ -173,12 +173,12 @@ public void testDenmarkLocaleRequestOnly() throws Exception { @Test public void testCountryOnlyLocale() throws Exception { - params.put(I18nInterceptor.DEFAULT_PARAMETER, "DK"); + params.put(I18nInterceptor.DEFAULT_PARAMETER, "NL"); interceptor.intercept(mai); assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed - Locale denmark = new Locale("DK"); + Locale denmark = new Locale("NL"); assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here assertEquals(denmark, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object } @@ -197,31 +197,31 @@ public void testLanguageOnlyLocale() throws Exception { @Test public void testWithVariant() throws Exception { - params.put(I18nInterceptor.DEFAULT_PARAMETER, "fr_CA_xx"); + params.put(I18nInterceptor.DEFAULT_PARAMETER, "ja_JP_JP"); interceptor.intercept(mai); assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed - Locale variant = new Locale("fr", "CA", "xx"); + Locale variant = new Locale("ja", "JP", "JP"); Locale locale = (Locale) session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE); assertNotNull(locale); // should be stored here assertEquals(variant, locale); - assertEquals("xx", locale.getVariant()); + assertEquals("JP", locale.getVariant()); } @Test public void testWithVariantRequestOnly() throws Exception { - params.put(I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER, "fr_CA_xx"); + params.put(I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER, "ja_JP_JP"); interceptor.intercept(mai); assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed assertNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); - Locale variant = new Locale("fr", "CA", "xx"); + Locale variant = new Locale("ja", "JP", "JP"); Locale locale = mai.getInvocationContext().getLocale(); assertNotNull(locale); // should be stored here assertEquals(variant, locale); - assertEquals("xx", locale.getVariant()); + assertEquals("JP", locale.getVariant()); } @Test
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- struts.apache.org/docs/s2-030.htmlnvdVendor AdvisoryWEB
- github.com/advisories/GHSA-2j4q-9fff-236jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-2162ghsaADVISORY
- github.com/apache/struts/blob/f511034acd7b97e07d281169b38e2af40c94903d/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.javaghsaWEB
- github.com/apache/struts/commit/fc2179cf1ac9fbfb61e3430fa88b641d87253327ghsaWEB
- web.archive.org/web/20210123095722/http://www.securityfocus.com/bid/85070ghsaWEB
- web.archive.org/web/20210801130539/http://www.securitytracker.com/id/1035272ghsaWEB
- www.securityfocus.com/bid/85070nvd
- www.securitytracker.com/id/1035272nvd
News mentions
0No linked articles in our index yet.