Apache ShenYu Password leakage
Description
Apache ShenYu 2.4.0 and 2.4.1 expose an unauthenticated endpoint that discloses all user passwords.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache ShenYu 2.4.0 and 2.4.1 expose an unauthenticated endpoint that discloses all user passwords.
Vulnerability
Apache ShenYu versions 2.4.0 and 2.4.1 contain an unauthenticated endpoint in the dashboard user controller that returns the list of all dashboard users, including their passwords. The endpoint lacked proper authorization checks, allowing any unauthenticated request to retrieve sensitive credential data [1][2].
Exploitation
An attacker can exploit this vulnerability by sending a GET request to the /dashboardUser endpoint without any authentication or special privileges. No user interaction or network position beyond basic HTTP access is required [2][3].
Impact
Successful exploitation results in the disclosure of all dashboard user passwords, which may be stored in encrypted form but are returned decrypted by the endpoint. An attacker can use these credentials to gain administrative access to the ShenYu Admin console, potentially compromising the entire API gateway configuration and managed services [2].
Mitigation
Users should upgrade to Apache ShenYu version 2.4.2 or later, which adds the @RequiresPermissions("system:manager:list") annotation to restrict access to the vulnerable endpoint [3][4]. No workarounds are available for versions 2.4.0 and 2.4.1.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.shenyu:shenyu-commonMaven | >= 2.4.0, < 2.4.2 | 2.4.2 |
Affected products
2Patches
10e826ceae97afix shenyu-admin: add dashboard user permission (#2357)
4 files changed · +31 −13
shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/DashboardUserController.java+15 −10 modified@@ -29,6 +29,7 @@ import org.apache.shenyu.admin.service.DashboardUserService; import org.apache.shenyu.admin.utils.AesUtils; import org.apache.shenyu.admin.utils.ShenyuResultMessage; +import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -70,14 +71,15 @@ public DashboardUserController(final SecretProperties secretProperties, final Da * @param pageSize page size * @return {@linkplain ShenyuAdminResult} */ + @RequiresPermissions("system:manager:list") @GetMapping("") - public ShenyuAdminResult queryDashboardUsers(final String userName, final Integer currentPage, final Integer pageSize) { - String key = secretProperties.getKey(); - String iv = secretProperties.getIv(); - CommonPager<DashboardUserVO> commonPager = dashboardUserService.listByPage(new DashboardUserQuery(userName, new PageParameter(currentPage, pageSize))); + public ShenyuAdminResult queryDashboardUsers(final String userName, + final Integer currentPage, + final Integer pageSize) { + CommonPager<DashboardUserVO> commonPager = dashboardUserService.listByPage(new DashboardUserQuery(userName, + new PageParameter(currentPage, pageSize))); + if (CollectionUtils.isNotEmpty(commonPager.getDataList())) { - commonPager.getDataList() - .forEach(item -> item.setPassword(AesUtils.aesDecryption(item.getPassword(), key, iv))); return ShenyuAdminResult.success(ShenyuResultMessage.QUERY_SUCCESS, commonPager); } else { return ShenyuAdminResult.error(ShenyuResultMessage.DASHBOARD_QUERY_ERROR); @@ -90,13 +92,13 @@ public ShenyuAdminResult queryDashboardUsers(final String userName, final Intege * @param id dashboard user id. * @return {@linkplain ShenyuAdminResult} */ + @RequiresPermissions("system:manager:list") @GetMapping("/{id}") public ShenyuAdminResult detailDashboardUser(@PathVariable("id") final String id) { DashboardUserEditVO dashboardUserEditVO = dashboardUserService.findById(id); - return Optional.ofNullable(dashboardUserEditVO).map(item -> { - item.setPassword(""); - return ShenyuAdminResult.success(ShenyuResultMessage.DETAIL_SUCCESS, item); - }).orElseGet(() -> ShenyuAdminResult.error(ShenyuResultMessage.DASHBOARD_QUERY_ERROR)); + return Optional.ofNullable(dashboardUserEditVO) + .map(item -> ShenyuAdminResult.success(ShenyuResultMessage.DETAIL_SUCCESS, item)) + .orElseGet(() -> ShenyuAdminResult.error(ShenyuResultMessage.DASHBOARD_QUERY_ERROR)); } /** @@ -105,6 +107,7 @@ public ShenyuAdminResult detailDashboardUser(@PathVariable("id") final String id * @param dashboardUserDTO dashboard user. * @return {@linkplain ShenyuAdminResult} */ + @RequiresPermissions("system:manager:add") @PostMapping("") public ShenyuAdminResult createDashboardUser(@Valid @RequestBody final DashboardUserDTO dashboardUserDTO) { String key = secretProperties.getKey(); @@ -123,6 +126,7 @@ public ShenyuAdminResult createDashboardUser(@Valid @RequestBody final Dashboard * @param dashboardUserDTO dashboard user. * @return {@linkplain ShenyuAdminResult} */ + @RequiresPermissions("system:manager:edit") @PutMapping("/{id}") public ShenyuAdminResult updateDashboardUser(@PathVariable("id") final String id, @Valid @RequestBody final DashboardUserDTO dashboardUserDTO) { String key = secretProperties.getKey(); @@ -139,6 +143,7 @@ public ShenyuAdminResult updateDashboardUser(@PathVariable("id") final String id * @param ids primary key. * @return {@linkplain ShenyuAdminResult} */ + @RequiresPermissions("system:manager:delete") @DeleteMapping("/batch") public ShenyuAdminResult deleteDashboardUser(@RequestBody @NotEmpty final List<@NotBlank String> ids) { Integer deleteCount = dashboardUserService.delete(ids);
shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/DashboardUserVO.java+2 −0 modified@@ -17,6 +17,7 @@ package org.apache.shenyu.admin.model.vo; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.apache.shenyu.admin.model.entity.DashboardUserDO; import org.apache.shenyu.common.utils.DateUtils; @@ -44,6 +45,7 @@ public class DashboardUserVO implements Serializable { /** * user password. */ + @JsonIgnore private String password; /**
shenyu-admin/src/main/java/org/apache/shenyu/admin/shiro/config/ShiroConfiguration.java+13 −0 modified@@ -24,6 +24,7 @@ import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -94,6 +95,18 @@ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor( return authorizationAttributeSourceAdvisor; } + /** + * Support shiro annotation. + * + * @return DefaultAdvisorAutoProxyCreator. + */ + @Bean + public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { + DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); + defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); + return defaultAdvisorAutoProxyCreator; + } + /** * shiro's lifecycle in spring. *
shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/DashboardUserControllerTest.java+1 −3 modified@@ -98,7 +98,6 @@ public void queryDashboardUsers() throws Exception { mockMvc.perform(get(url)) .andExpect(status().isOk()) .andExpect(jsonPath("$.message", is(ShenyuResultMessage.QUERY_SUCCESS))) - .andExpect(jsonPath("$.data.dataList[0].password", is("123456"))) .andReturn(); final CommonPager<DashboardUserVO> commonPagerError = new CommonPager<>(new PageParameter(), @@ -121,8 +120,7 @@ public void detailDashboardUser() throws Exception { final String url = "/dashboardUser/1"; mockMvc.perform(get(url)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.message", is(ShenyuResultMessage.DETAIL_SUCCESS))) - .andExpect(jsonPath("$.data.password", is(""))); + .andExpect(jsonPath("$.message", is(ShenyuResultMessage.DETAIL_SUCCESS))); given(dashboardUserService.findById(any())).willReturn(null); mockMvc.perform(get(url))
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-7wq4-89xx-g62jghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-23223ghsaADVISORY
- www.openwall.com/lists/oss-security/2022/01/25/7ghsamailing-listx_refsource_MLISTWEB
- www.openwall.com/lists/oss-security/2022/01/26/4ghsamailing-listx_refsource_MLISTWEB
- github.com/apache/incubator-shenyu/releases/tag/v2.4.2ghsaWEB
- github.com/apache/shenyu/commit/0e826ceae97a1258cb15c73a3072118c920e8654ghsaWEB
- github.com/apache/shenyu/pull/2357ghsaWEB
- lists.apache.org/thread/q2gg6ny6lpkph7nkrvjzqdvqpm805v8sghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.