
Dapr 1.11.2 安全补丁深度解析API Token 绕过修复、Workflow 状态保存缺陷与 gRPC 配置订阅竞态修复【免费下载链接】daprDapr is a portable runtime for building distributed applications across cloud and edge, combining event-driven architecture with workflow orchestration.项目地址: https://gitcode.com/GitHub_Trending/da/daprDapr 1.11.2 是 Dapr 1.11 系列的重要安全补丁版本聚焦于修复两个已公开的安全漏洞高危的 API Token 认证绕过、avro 第三方依赖导致的潜在 DoS以及 Dapr Workflow 引擎与 gRPC Configuration Subscribe API 的多个功能缺陷。本文以该版本官方发布说明为主线结合当前仓库源码逐项剖析每个问题的触发条件、影响范围、根因与修复方案帮助开发者理解升级必要性并掌握 API Token 认证、Workflow 状态持久化与配置订阅的底层实现原理。版本概览一次安全驱动的补丁发布Dapr 1.11.2 是一个以安全修复为主、附带功能缺陷修复的补丁版本主要内容分为两部分安全修复Security fixesAPI Token 认证在 HTTP 端点中的绕过漏洞avro 依赖导致的潜在 DoSCVE-2023-37475缺陷修复Bug fixesWorkflow 中无界的历史批次保存问题Workflow 在某些 Kubernetes 集群中无法工作的问题gRPC Configuration Subscribe API 的多个缺陷下文将按官方发布说明的顺序逐项深入解析。安全修复一HTTP 端点的 API Token 认证绕过问题描述Dapr sidecar 使用API Token 认证机制来验证来自应用程序的调用。该机制通过在 sidecar 中设置DAPR_API_TOKEN环境变量对应常量定义见 pkg/security/consts/consts.go并要求应用在调用 sidecar HTTP API 时通过dapr-api-tokenHTTP 头携带相同的令牌常量定义见 pkg/security/consts/consts.go。1.11.2 之前的版本存在一个高危漏洞只要请求 URL包括查询字符串中包含/healthz字样即可绕过 API Token 认证直接访问 sidecar 的 HTTP API。影响范围官方发布说明明确指出该漏洞影响所有使用 API Token 认证、且 Dapr 版本为1.10.9 与 1.11.2的用户。根因剖析问题的根源在于 sidecar 中 API Token 认证中间件的实现方式。从当前仓库的修复后代码 pkg/api/http/middlewares.go 可以看到修复后的APITokenAuthMiddleware逻辑如下// APITokenAuthMiddleware enforces authentication using the dapr-api-token header. func APITokenAuthMiddleware(token string) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { if token { return next } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { v : r.Header.Get(securityConsts.APITokenHeader) if v ! token !isRouteExcludedFromAPITokenAuth(r.Method, r.URL) { http.Error(w, invalid api token, http.StatusUnauthorized) return } r.Header.Del(securityConsts.APITokenHeader) next.ServeHTTP(w, r) }) } }修复前的问题旧实现以URL 中是否包含/healthz子串作为放行依据而不是精确匹配健康检查端点路径。这意味着/v1.0/invoke/myapp/method/healthz这类业务调用路径中包含healthz的请求会被错误放行/v1.0/invoke/myapp/method/something?foo/healthz这类查询字符串中包含healthz的请求也会被错误放行攻击者可以构造精心设计的 URL让任意 API 请求如状态读写、服务调用绕过认证。修复后的策略认证中间件仅对健康检查端点进行严格的精确路径匹配且只放行 GET 方法func isRouteExcludedFromAPITokenAuth(method string, u *url.URL) bool { path : strings.Trim(u.Path, /) switch path { case apiVersionV1 /healthz: return method http.MethodGet case apiVersionV1 /healthz/outbound: return method http.MethodGet default: return false } }从源码可以看到修复后的关键变化只检查u.Path路径部分完全忽略查询字符串杜绝了?foo/healthz这类绕过手法精确匹配完整路径仅放行/v1.0/healthz和/v1.0/healthz/outbound两个端点不再使用子串匹配限制 HTTP 方法为 GET其他方法如 PUT、POST即使路径匹配也会被拒绝。测试用例验证修复后的行为在 pkg/api/http/middlewares_test.go 中有完整的单元测试覆盖测试用例矩阵清晰展示了边界情况测试场景请求预期结果健康检查GET /v1.0/healthz放行出站健康检查GET /v1.0/healthz/outbound放行带查询参数的合法健康检查GET /v1.0/healthz?appidmyapp放行结尾斜杠GET /v1.0/healthz/放行会被斜杠剥离逻辑处理非 GET 方法PUT /v1.0/healthz拒绝401路径中包含 healthz 的业务调用GET /v1.0/invoke/myapp/method/healthz拒绝401查询字符串包含 healthzGET /v1.0/invoke/myapp/method/something?foo/healthz拒绝401其中路径中包含 healthz 的业务调用和查询字符串包含 healthz两个用例正是对原漏洞利用手法的直接回归防护。升级与加固建议立即升级使用 API Token 认证设置了DAPR_API_TOKEN或APP_API_TOKEN的用户应尽快升级到包含该修复的版本。理解认证模型API Token 由 pkg/security/token.go 中的GetAPIToken/GetAppToken从环境变量读取应用调用 sidecar 时必须通过dapr-api-token头传递令牌。纵深防御即使升级后也建议结合 Dapr 的 API 允许列表allowlists 等机制限制 sidecar API 的访问范围。安全修复二avro 依赖的潜在 DoSCVE-2023-37475问题描述Dapr 的第三方依赖avroApache Avro 序列化库存在一个已知问题CVE-2023-37475可能导致资源耗尽resource exhaustion进而引发针对 Dapr 的拒绝服务攻击DoS。影响范围该问题影响使用 Pulsar 组件的 Dapr 用户。Pulsar 组件在消息编解码过程中会依赖 avro 库。根因与修复方案根因位于第三方依赖本身而非 Dapr 自身代码。修复方案是将 avro 依赖升级到 2.13.0该版本包含对 CVE-2023-37475 的修复。从当前仓库的 go.mod 可以看到 avro 依赖已演进为github.com/iskorotkov/avro/v2 v2.33.1且 go.mod 中还有注释说明该 fork 对 avro 的利用方式。这也印证了 Dapr 后续版本持续跟进 avro 依赖上游修复的维护策略。对用户的启示使用 Pulsar 绑定的用户应升级 Dapr 到包含该修复的版本在升级前可通过go list -m all等命令检查自己构建的 Dapr 二进制中所依赖的 avro 版本关注依赖漏洞扫描如 govulncheck、Dependabot报告保持依赖链健康。缺陷修复一Workflow 中无界的历史批次保存问题描述Workflow 引擎存在一个 bug每次检查点checkpoint保存时都会保存完整的 workflow 历史而不是仅保存增量deltas。这导致两个后果保存 workflow 状态的I/O 成本随 workflow 生命周期不断增长对于对事务批大小有限制的状态存储如 Azure Cosmos DB包含较多 action 的 workflow 会永久性失败。影响范围该问题影响Dapr 1.10 及以上版本使用 Dapr Workflow 的用户。根因剖析根因是一个典型的编码错误对象以引用reference方式传递而不是以指针pointer方式传递导致保存逻辑无法区分新增的历史事件与完整历史每次检查点都序列化并写入了全部历史。为了理解修复的意义可以看当前仓库中 Workflow 状态层的设计。在 pkg/runtime/wfengine/state/state.go 中historyAddedCount/historyRemovedCountstate.go用于跟踪自上次保存以来新增/移除的历史事件数量状态层按需写入新增的历史事件s.historyAddedCount len(newHistoryEvents)并在每次保存后重置计数state.gometadata 中记录了 history 长度等信息用于确定加载/保存时需要读写的 key 范围见 pkg/runtime/wfengine/README.md。Workflow 的持久化采用history-NNNNNN多 key 追加式存储方案而不是把整个历史序列化为单个 blob。正如 pkg/runtime/wfengine/README.md 所述这种设计正是为了支持高效增量更新if the full history would need to be serialized instead of just inserting incremental additions (the history is an append-only log of events)——即只插入增量追加事件而非序列化全部历史。而 1.11.2 修复的 bug 恰恰违背了这一设计初衷。修复方案官方在源码中修复了该编码问题并新增了测试防止回归。从当前仓库的 pkg/runtime/wfengine/backends/actors/actors_test.go-TODO 可以看到测试中对保存操作的断言逻辑如upsertCount的计数用于验证保存的是增量事件10x history metadata customStatus而非无界的完整历史。缺陷修复二Workflow 在某些 Kubernetes 集群中无法工作问题描述在某些 Kubernetes 集群中workflow 引擎可能无法处理 workflow 中的 work items 和 tasks调用 workflow 引擎会超时并失败。影响范围该问题影响满足以下条件的用户使用 Dapr WorkflowDapr gRPC 服务器监听多个地址。在 Kubernetes 上这是默认行为——Dapr 通常同时监听127.0.0.1IPv4和[::1]IPv6。在 Kubernetes 之外如果用户通过--dapr-listen-addresses指定了多个监听地址也可能触发该问题。根因剖析根因是初始化代码的设计缺陷每个 Dapr gRPC 监听器都独立附加了一个新的 workflow 引擎实例。当应用通过不同协议IPv4 或 IPv6连接 Dapr 时请求可能落到一个当前未在处理任务的 workflow 引擎上导致死锁deadlock。修复方案官方修改了初始化代码确保Dapr 在所有监听器之间共享单个 workflow 引擎实例。从当前仓库的运行时初始化代码可以印证这一设计。在 pkg/runtime/runtime.go 中wfe, err : wfengine.New(wfengine.Options{ AppID: runtimeConfig.id, Namespace: namespace, Actors: actors, Spec: globalConfig.Spec.WorkflowSpec, BackendManager: processor.WorkflowBackend(), // ... }) if err ! nil { return nil, err } // Install the wfengine as the processors internal workflow registrar. processor.SetInProcessWorkflows(wfe)workflow 引擎wfengine在运行时初始化阶段只创建一次并作为运行时结构体字段runtime.go 中的wfengine wfengine.Interface在多个 API 服务器间共享如 runtime.go 与 runtime.go 中WorkflowEngine: a.wfengine的注入而不是为每个 gRPC 监听器各自创建实例。这与 1.11.2 的修复方向一致单一共享实例避免请求命中空闲引擎导致死锁。缺陷修复三gRPC Configuration Subscribe API 的多个缺陷问题描述gRPC 版本的Configuration Subscribe API存在多个 bug尤其是竞态条件race conditions。该 API 在 Dapr 1.11.0 中转为稳定版GA但实现中遗留的竞态问题可能导致 Subscribe API 行为异常。影响范围该问题影响使用 gRPC 调用 Configuration building block API的用户。根因剖析问题根源在于gRPC 流stream处理方式存在多个竞态条件。在 pkg/api/grpc/grpc.go 中SubscribeConfiguration通过 gRPC server-streaming 持续向客户端推送配置变更事件涉及订阅 ID 的注册AddConfigurationSubscribe见 grpc.go、事件的流式发送handler.serverStream.Send以及取消订阅时的清理DeleteConfigurationSubscribe见 grpc.go。这些并发操作之间的同步若不严谨就会出现数据竞争。修复方案官方对代码进行了重构移除了竞态条件并修复了相关 bug。当前仓库中该 API 的注册入口在 pkg/api/grpc/endpoints.go同时保留了SubscribeConfigurationAlpha1作为兼容别名grpc.go对应测试见 pkg/api/grpc/grpc_test.go 的TestSubscribeConfiguration。对用户的建议使用 gRPC Configuration building block如配置热更新场景的用户应升级到该修复版本并在升级后对订阅/取消订阅的并发场景进行回归验证。升级指引与注意事项升级前的检查清单确认受影响面是否启用了 API Token 认证DAPR_API_TOKEN/APP_API_TOKEN是则受安全漏洞一影响是否使用 Pulsar 组件是则受安全漏洞二影响是否使用 Dapr Workflow版本 1.10是则可能受 Workflow 两个缺陷影响是否通过 gRPC 调用 Configuration Subscribe API是则可能受竞态缺陷影响。对照版本号官方发布说明明确指出受影响版本为Dapr 1.10.9 和 1.11.2使用这些版本的用户应尽快升级到 1.11.2 或更高版本。升级后的验证要点安全验证带 token 的业务调用正常、不带 token 或 token 错误的调用返回 401确认GET /v1.0/healthz仍无需 token 可访问供 Kubernetes 探针使用但路径中包含 healthz 的业务端点必须要求认证Workflow在有多个 gRPC 监听地址Kubernetes 默认 IPv4IPv6的环境验证 workflow 可正常执行对含大量 action 的 workflow 验证状态保存不再增长无界Configuration Subscribe并发订阅/取消订阅多个配置项验证事件推送行为符合预期。总结Dapr 1.11.2 通过一次紧凑的补丁发布同时解决了安全与稳定性两个维度的问题类别问题关键修复点安全高危API Token 认证绕过健康检查端点从子串匹配改为精确路径匹配仅放行 GET安全CVE-2023-37475avro 依赖 DoS升级 avro 依赖至修复版本功能Workflow 无界历史保存修复引用/指针传递错误仅保存增量历史功能Workflow 多监听地址死锁所有 gRPC 监听器共享单一 workflow 引擎实例功能gRPC 配置订阅竞态重构流处理代码消除竞态条件对于安全敏感的生产环境这五个修复点共同构成了升级到 1.11.2或更高版本的充分理由。若需了解各修复在源码中的具体体现可继续研读本仓库中的 HTTP 认证中间件、运行时初始化、Workflow 状态层 与 gRPC 配置订阅实现 等关键文件。【免费下载链接】daprDapr is a portable runtime for building distributed applications across cloud and edge, combining event-driven architecture with workflow orchestration.项目地址: https://gitcode.com/GitHub_Trending/da/dapr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考