Server-Side Request Forgery in Apache ShenYu
Description
Apache ShenYu 2.5.1 suffers from an SSRF vulnerability in the /sandbox/proxyGateway endpoint, allowing full control over HTTP requests to arbitrary hosts.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache ShenYu 2.5.1 suffers from an SSRF vulnerability in the /sandbox/proxyGateway endpoint, allowing full control over HTTP requests to arbitrary hosts.
The vulnerability is an SSRF (Server-Side Request Forgery) issue in Apache ShenYu version 2.5.1, specifically within the /sandbox/proxyGateway endpoint [1]. An attacker can supply an arbitrary URL via the requestUrl parameter, and the server will fetch that URL and return the response. The key technical detail is that the attacker also controls the HTTP method, cookies, IP address, and headers, enabling the construction of complete, arbitrary HTTP requests to any host [1].
Attack
Vector Exploitation requires network access to the ShenYu admin interface where the /sandbox/proxyGateway endpoint is exposed. There is no authentication bypass needed for the endpoint itself; the attacker simply sends a crafted HTTP request to the vulnerable endpoint with a chosen target URL and desired HTTP headers, cookies, etc. This allows the attacker to probe internal network services, access cloud metadata endpoints, or perform other actions that appear to originate from the ShenYu server [1].
Impact
A successful attack enables an external attacker to make requests to internal or external hosts as if they were the ShenYu server. This can lead to information disclosure (e.g., reading internal service responses, cloud metadata), privilege escalation, or further lateral movement within the network [1]. Since the attacker controls the full HTTP request, they can also attempt to exploit other services that may trust requests from the ShenYu server.
Mitigation
The vulnerability has been patched in Apache ShenYu version 2.6.0, and the fix is available via pull request #4776 [3]. Users should upgrade to Apache ShenYu 2.6.0 or apply the relevant patch to restrict the /sandbox/proxyGateway endpoint to only whitelisted gateway addresses [3]. No workaround is provided for earlier versions.
AI Insight generated on May 20, 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-adminMaven | < 2.6.0 | 2.6.0 |
org.apache.shenyu:shenyu-commonMaven | < 2.6.0 | 2.6.0 |
Affected products
3- ghsa-coords2 versions
< 2.6.0+ 1 more
- (no CPE)range: < 2.6.0
- (no CPE)range: < 2.6.0
Patches
11fd33d5aa032[Task #4774] <The access layer interface for the apidoc function only allows requests for gateway addresses within the whitelist.> (#4776)
2 files changed · +57 −6
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SandboxServiceImpl.java+31 −1 modified@@ -17,19 +17,24 @@ package org.apache.shenyu.admin.service.impl; +import java.util.Set; import okhttp3.Response; import okhttp3.ResponseBody; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.shenyu.admin.model.dto.ProxyGatewayDTO; import org.apache.shenyu.admin.model.entity.AppAuthDO; +import org.apache.shenyu.admin.model.vo.ShenyuDictVO; import org.apache.shenyu.admin.service.AppAuthService; import org.apache.shenyu.admin.service.SandboxService; +import org.apache.shenyu.admin.service.ShenyuDictService; import org.apache.shenyu.admin.utils.Assert; import org.apache.shenyu.admin.utils.HttpUtils; import org.apache.shenyu.admin.utils.ShenyuSignatureUtils; import org.apache.shenyu.admin.utils.UploadUtils; +import org.apache.shenyu.common.constant.AdminConstants; import org.apache.shenyu.common.constant.Constants; +import org.apache.shenyu.common.exception.ShenyuException; import org.apache.shenyu.common.utils.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,8 +68,11 @@ public class SandboxServiceImpl implements SandboxService { private final AppAuthService appAuthService; - public SandboxServiceImpl(final AppAuthService appAuthService) { + private final ShenyuDictService shenyuDictService; + + public SandboxServiceImpl(final AppAuthService appAuthService, final ShenyuDictService shenyuDictService) { this.appAuthService = appAuthService; + this.shenyuDictService = shenyuDictService; } @Override @@ -74,6 +82,14 @@ public void requestProxyGateway(final ProxyGatewayDTO proxyGatewayDTO, final Htt String appKey = proxyGatewayDTO.getAppKey(); UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(proxyGatewayDTO.getRequestUrl()).build(); + String proxyHostPort = getHostPort(proxyGatewayDTO.getRequestUrl()); + + Set<String> permitHostPorts = getPermitHostPorts(); + if (!permitHostPorts.contains(proxyHostPort)) { + LOG.error("Unsecure access, details: {}", proxyGatewayDTO.getRequestUrl()); + throw new ShenyuException(proxyHostPort + " is not allowed."); + } + String signContent = null; String sign = null; if (StringUtils.isNotEmpty(appKey)) { @@ -106,6 +122,20 @@ public void requestProxyGateway(final ProxyGatewayDTO proxyGatewayDTO, final Htt response.flushBuffer(); } + private Set<String> getPermitHostPorts() { + List<ShenyuDictVO> dictVOList = shenyuDictService.list(AdminConstants.DICT_TYPE_API_DOC_ENV); + Set<String> hostPorts = dictVOList.stream() + .filter(ShenyuDictVO::getEnabled) + .map(dictVO -> getHostPort(dictVO.getDictValue())) + .collect(Collectors.toSet()); + return hostPorts; + } + + private String getHostPort(final String httpUrl) { + UriComponents uriComponent = UriComponentsBuilder.fromHttpUrl(httpUrl).build(); + return uriComponent.getHost() + ":" + org.apache.shenyu.common.utils.UriUtils.getActualPort(uriComponent.getScheme(), uriComponent.getPort()); + } + private Map<String, String> buildReqHeaders(final ProxyGatewayDTO proxyGatewayDTO) { Map<String, String> reqHeaders = new HashMap<>(); try {
shenyu-common/src/main/java/org/apache/shenyu/common/utils/UriUtils.java+26 −5 modified@@ -26,9 +26,9 @@ * uri util. */ public class UriUtils { - + private static final String PRE_FIX = "/"; - + /** * create URI {@link URI}. * @@ -41,7 +41,7 @@ public static URI createUri(final String uri) { } return null; } - + /** * Repair data string. * @@ -51,7 +51,7 @@ public static URI createUri(final String uri) { public static String repairData(final String name) { return name.startsWith(PRE_FIX) ? name : PRE_FIX + name; } - + /** * Remove prefix string. * @@ -80,7 +80,7 @@ public static String getPathWithParams(final URI uri) { * appendScheme. * * @param scheme scheme - * @param url url + * @param url url * @return {@link String} */ public static String appendScheme(final String url, final String scheme) { @@ -90,4 +90,25 @@ public static String appendScheme(final String url, final String scheme) { } return schemeUrl; } + + /** + * get actual port. + * + * @param scheme scheme eg:http + * @param port port + * @return {@link int} + */ + public static int getActualPort(final String scheme, final Integer port) { + Integer actualPort = port; + if (Objects.isNull(port) || port.intValue() < 0) { + if (!"http".equals(scheme) && !"ws".equals(scheme)) { + if ("https".equals(scheme) || "wss".equals(scheme)) { + actualPort = 443; + } + } else { + actualPort = 80; + } + } + return actualPort; + } }
Vulnerability mechanics
Root cause
"Missing host/port whitelist validation in the /sandbox/proxyGateway endpoint allows an attacker to send arbitrary HTTP requests to any target."
Attack vector
An attacker sends a POST request to the /sandbox/proxyGateway endpoint with a crafted requestUrl parameter pointing to an arbitrary external or internal host. The attacker can also control the HTTP method, cookies, IP address, and headers via the ProxyGatewayDTO fields. Because the original code performed no validation on the target host, the server would blindly forward the request, enabling SSRF attacks against internal services or external systems. The vulnerability is exploitable without authentication if the endpoint is exposed.
Affected code
The vulnerable code is in `SandboxServiceImpl.requestProxyGateway()` at `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SandboxServiceImpl.java`. The method directly used the user-supplied `requestUrl` from `ProxyGatewayDTO` to build and execute an HTTP request via `HttpUtils.execute()` without any host validation. The patch adds a whitelist check using `getPermitHostPorts()` and a new `getHostPort()` helper, along with a supporting `UriUtils.getActualPort()` method in `shenyu-common` [patch_id=1641014].
What the fix does
The patch adds a whitelist check in `SandboxServiceImpl.requestProxyGateway()` by extracting the host and port from the user-supplied URL via the new `getHostPort()` helper. It then compares that value against a set of permitted host:port entries obtained from the `shenyu_dict` table where the dictionary type is `API_DOC_ENV` and the entry is enabled. If the target is not in the whitelist, the method throws a `ShenyuException` and logs the blocked URL. A new utility method `UriUtils.getActualPort()` was also added to correctly resolve default ports (80 for http/ws, 443 for https/wss) when the URL omits an explicit port [patch_id=1641014].
Preconditions
- networkThe attacker must be able to reach the Apache ShenYu admin /sandbox/proxyGateway endpoint.
- inputThe attacker must supply a requestUrl parameter pointing to a target host of their choice.
Generated on May 23, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-7w8v-5fcq-pvqwghsaADVISORY
- lists.apache.org/thread/chprswxvb22z35vnoxv9tt3zknsm977dghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2023-25753ghsaADVISORY
- github.com/apache/shenyu/pull/4776ghsaWEB
News mentions
0No linked articles in our index yet.