dapr v1.15.14 版本更新介绍
发布日期: 2026-04-16
版本号: v1.15.14
Dapr 1.15.14版本包含一项关键安全修复:解决了服务调用路径中的特殊字符和路径遍历序列可能绕过访问控制策略的安全漏洞。攻击者若能访问Dapr的HTTP或gRPC API,可能利用编码技巧(如路径遍历
admin%2F..%2Fpublic、特殊字符#或%等)误导ACL策略判断,从而访问本应被禁止的目标路径。根本原因在于访问控制层与请求分发层对方法路径的处理方式不一致。修复方案是在服务调用边缘统一进行路径标准化处理,确保ACL检查和实际请求使用相同的标准化路径,并移除了ACL组件中的URL规范化依赖。此外,本版本还将Go升级至v1.25.9以修复相关漏洞。建议用户尽快升级至此版本。
更新内容 (中文)
Dapr 1.15.14
此更新包含一项关键安全修复:
安全:服务调用路径遍历绕过访问控制策略
问题
服务调用方法路径中的保留URL字符和路径遍历序列可能绕过访问控制策略。 能够访问 Dapr HTTP 或 gRPC API 的攻击者,可能调用目标应用程序上 ACL 配置为拒绝的操作。
影响
所有使用访问控制策略进行服务调用的部署均受影响。能够访问 Dapr API(HTTP 或 gRPC)的攻击者可能:
- 使用编码的路径遍历(
admin%2F..%2Fpublic)来访问允许的路径(/public),即使该方法从被拒绝的前缀(/admin)开始。 - 使用编码的片段(
%23)或查询(%3F)字符,导致 ACL 评估的路径与实际传递给目标应用程序的路径不同。 - 使用裸露的
%来破坏 ACL 规范化,可能完全绕过策略。
gRPC API 是更危险的攻击向量,因为 gRPC 将方法作为原始字符串传递,没有客户端 URL 清理——#、?、%、../ 和控制字符均按原样传递。
根本原因
方法路径在两个位置被独立规范化:
- ACL 使用
purell.NormalizeURLString,将方法视为 URL——解码%XX、解析../,并将#作为片段分隔符、?作为查询分隔符去除。 - 调度层(HTTP 的
constructRequest、gRPC 直通)使用原始方法字符串。
这造成了不匹配:ACL 授权了一个路径,而目标应用程序收到了不同的路径。例如,admin%2F..%2Fpublic 被 ACL 规范化为 public(允许),但目标应用程序接收到的是原始的 admin/../public。
解决方案
方法路径现在在服务调用边缘进行规范化——在 HTTP 和 gRPC 公共 API 调用的 directMessaging.Invoke 中,在 gRPC 内部调用的 callLocalValidateACL 中,以及在代理调用的 gRPC 代理处理程序中。规范化的形式同时用于 ACL 检查和出站调度,消除了不匹配。ACL 是一个纯粹的策略评估层,本身不执行任何规范化。
对于 HTTP,Go 的 net/http 服务器在提取方法之前,会在 r.URL.Path 中解码百分比编码。对于 gRPC,方法字符串是原始的(无百分比解码),被视为不透明——%2F 等百分比编码序列是字面字符,而非路径分隔符。
规范化使用 path.Clean 来解析 ../ 和重复斜杠,并拒绝包含 #、?、空字节或控制字符的方法路径。ACL 路径中已移除 purell 依赖。
作为纵深防御,HTTP 通道中的 constructRequest 在构建出站 URL 之前,会对方法应用 path.Clean。
强烈建议用户升级到此版本。
Go:更新至 v1.25.9
将 Go 版本更新以涵盖 1.24 系列中的 CVE。
更新内容 (原始)
Dapr 1.15.14
This update contains a critical security fix:
Security: Service invocation path traversal bypasses access control policies
Problem
Reserved URL characters and path traversal sequences in service invocation method paths could bypass access control policies. An attacker with access to the Dapr HTTP or gRPC API could invoke operations on a target application that the ACL was configured to deny.
Impact
Any deployment using access control policies for service invocation is affected. An attacker who can reach the Dapr API (HTTP or gRPC) could:
- Use encoded path traversal (
admin%2F..%2Fpublic) to reach an allowed path (/public) while the method started from a denied prefix (/admin). - Use encoded fragment (
%23) or query (%3F) characters to cause the ACL to evaluate a different path than what was delivered to the target application. - Use a bare
%to crash the ACL normalization, potentially bypassing the policy entirely.
The gRPC API was the more dangerous vector because gRPC passes the method as a raw string with no client-side URL sanitization — #, ?, %, ../, and control characters were all delivered literally.
Root Cause
The method path was normalized independently in two places:
- The ACL used
purell.NormalizeURLStringwhich treated the method as a URL — decoding%XX, resolving../, and stripping#as a fragment delimiter and?as a query delimiter. - The dispatch layer (
constructRequestfor HTTP, gRPC passthrough) used the raw method string.
This created a mismatch: the ACL authorized one path while the target application received a different one. For example, admin%2F..%2Fpublic was normalized by the ACL to public (allowed), but the target application received the raw admin/../public.
Solution
The method path is now normalized at the service invocation edge — in directMessaging.Invoke for HTTP and gRPC public API calls, in callLocalValidateACL for gRPC internal calls, and in the gRPC proxy handler for proxied calls. The normalized form is used for both the ACL check and the outbound dispatch, eliminating the mismatch. The ACL is a pure policy evaluation layer and performs no normalization of its own.
For HTTP, Go’s net/http server decodes percent-encoding in r.URL.Path before the method is extracted. For gRPC, method strings are raw (no percent-decoding) and are treated as opaque — percent-encoded sequences like %2F are literal characters, not path separators.
Normalization uses path.Clean to resolve ../ and duplicate slashes, and rejects method paths containing #, ?, null bytes, or control characters. The purell dependency has been removed from the ACL path.
As defense-in-depth, constructRequest in the HTTP channel applies path.Clean to the method before building the outbound URL.
Users are strongly encouraged to upgrade to this release.
Go: Update to v1.25.9
Update Go version to cover CVEs in the 1.24 line.
下载链接
- daprd_darwin_amd64.tar.gz
- daprd_darwin_amd64.tar.gz.sha256
- daprd_darwin_arm64.tar.gz
- daprd_darwin_arm64.tar.gz.sha256
- daprd_linux_amd64-stablecomponents.tar.gz
- daprd_linux_amd64-stablecomponents.tar.gz.sha256
- daprd_linux_amd64.tar.gz
- daprd_linux_amd64.tar.gz.sha256
- daprd_linux_arm-stablecomponents.tar.gz
- daprd_linux_arm-stablecomponents.tar.gz.sha256
- daprd_linux_arm.tar.gz
- daprd_linux_arm.tar.gz.sha256
- daprd_linux_arm64-stablecomponents.tar.gz
- daprd_linux_arm64-stablecomponents.tar.gz.sha256
- daprd_linux_arm64.tar.gz
- daprd_linux_arm64.tar.gz.sha256
- daprd_windows_amd64.zip
- daprd_windows_amd64.zip.sha256
- grafana-actor-dashboard.json
- grafana-actor-dashboard.json.sha256
- grafana-sidecar-dashboard.json
- grafana-sidecar-dashboard.json.sha256
- grafana-system-services-dashboard.json
- grafana-system-services-dashboard.json.sha256
- injector_darwin_amd64.tar.gz
- injector_darwin_amd64.tar.gz.sha256
- injector_darwin_arm64.tar.gz
- injector_darwin_arm64.tar.gz.sha256
- injector_linux_amd64.tar.gz
- injector_linux_amd64.tar.gz.sha256
- injector_linux_arm.tar.gz
- injector_linux_arm.tar.gz.sha256
- injector_linux_arm64.tar.gz
- injector_linux_arm64.tar.gz.sha256
- injector_windows_amd64.zip
- injector_windows_amd64.zip.sha256
- operator_darwin_amd64.tar.gz
- operator_darwin_amd64.tar.gz.sha256
- operator_darwin_arm64.tar.gz
- operator_darwin_arm64.tar.gz.sha256
- operator_linux_amd64.tar.gz
- operator_linux_amd64.tar.gz.sha256
- operator_linux_arm.tar.gz
- operator_linux_arm.tar.gz.sha256
- operator_linux_arm64.tar.gz
- operator_linux_arm64.tar.gz.sha256
- operator_windows_amd64.zip
- operator_windows_amd64.zip.sha256
- placement_darwin_amd64.tar.gz
- placement_darwin_amd64.tar.gz.sha256
- placement_darwin_arm64.tar.gz
- placement_darwin_arm64.tar.gz.sha256
- placement_linux_amd64.tar.gz
- placement_linux_amd64.tar.gz.sha256
- placement_linux_arm.tar.gz
- placement_linux_arm.tar.gz.sha256
- placement_linux_arm64.tar.gz
- placement_linux_arm64.tar.gz.sha256
- placement_windows_amd64.zip
- placement_windows_amd64.zip.sha256
- scheduler_darwin_amd64.tar.gz
- scheduler_darwin_amd64.tar.gz.sha256
- scheduler_darwin_arm64.tar.gz
- scheduler_darwin_arm64.tar.gz.sha256
- scheduler_linux_amd64.tar.gz
- scheduler_linux_amd64.tar.gz.sha256
- scheduler_linux_arm.tar.gz
- scheduler_linux_arm.tar.gz.sha256
- scheduler_linux_arm64.tar.gz
- scheduler_linux_arm64.tar.gz.sha256
- scheduler_windows_amd64.zip
- scheduler_windows_amd64.zip.sha256
- sentry_darwin_amd64.tar.gz
- sentry_darwin_amd64.tar.gz.sha256
- sentry_darwin_arm64.tar.gz
- sentry_darwin_arm64.tar.gz.sha256
- sentry_linux_amd64.tar.gz
- sentry_linux_amd64.tar.gz.sha256
- sentry_linux_arm.tar.gz
- sentry_linux_arm.tar.gz.sha256
- sentry_linux_arm64.tar.gz
- sentry_linux_arm64.tar.gz.sha256
- sentry_windows_amd64.zip
- sentry_windows_amd64.zip.sha256