CVE-2026-31886Dagu是一款内置Web用户界面的工作流引擎。在2.2.4之前的版本中,内联DAG执行端点接受的dagRunId请求字段被直接传递给filepath.Join来构造临时目录路径,但未进行任何格式验证。Go语言的filepath.Join会按字面方式解析".."路径段,因此攻击者可以通过提供类似".."的值来重定向计算出的目录,使其超出预期的/tmp/<name>/<id>路径范围。一个延迟清理函数会调用os.RemoveAll对该目录进行无条件删除,从而删除路径遍历解析后的任意目录。当dagRunId设置为".."时,解析的目录是系统临时目录(Linux上的/tmp)。在非root部署中,os.RemoveAll("/tmp")会删除dagu进程用户拥有的/tmp中的所有文件,破坏所有在/tmp中有活动临时文件的并发dagu运行。在root或Docker部署中,该调用会删除/tmp的全部内容,导致系统范围的拒绝服务。此漏洞已在2.2.4版本中修复。
漏洞根源在于Dagu工作流引擎的inline DAG执行端点对dagRunId参数缺乏输入验证。当用户发起DAG执行请求时,后端代码将dagRunId直接传入Go标准库的filepath.Join函数来构建临时目录路径。filepath.Join在处理路径时会对".."进行字面解析而不会进行安全检查,这允许攻击者构造恶意请求使目录路径跳出预期的沙箱范围。具体攻击场景:攻击者构造dagRunId为".."的请求,filepath.Join("/tmp/dagu", "..")会解析为"/tmp",随后HTTP处理器返回时,延迟清理函数会执行os.RemoveAll("/tmp"),导致整个/tmp目录被清空。在容器化部署中,这可能导致整个系统临时存储被删除,引发连锁反应式的拒绝服务攻击。