基于Action Cable的非阻塞长时请求实现方案及安全性咨询
你这套基于Rails Action Cable实现的非阻塞长时请求处理方案整体设计合理,能有效解决PDF/CSV生成这类耗时请求阻塞服务端的问题,但确实存在以下几处可被利用的安全隐患:
未校验客户端传入的参数,存在注入风险
你的download_pdf控制器方法直接将params[:content_disposition]、params[:request_button_id]等用户可控参数透传给后台任务,没有做任何合法性校验:content_disposition参数如果被攻击者篡改,传入恶意的头内容(比如inline; filename=xxx.exe或者包含换行符的注入payload),后续你在设置文件下载响应头时会触发HTTP响应头注入漏洞,甚至诱导用户下载恶意文件。- 三个按钮ID参数如果被传入包含特殊字符的恶意值,前端接收广播后直接拼接进
querySelector选择器可能导致逻辑异常,极端情况下如果后续有逻辑把ID值插入DOM还会触发XSS漏洞。
修复建议:控制器层校验content_disposition只允许传入inline/attachment两个合法值,按钮ID参数做格式校验,只允许字母、数字、下划线这类合法的DOM ID字符。
缺少请求频率限制,存在拒绝服务风险
目前没有对PDF生成请求做频率限制,攻击者可以批量提交大量生成请求,占满Resque队列,耗尽服务端计算、存储资源,导致正常用户的请求无法处理。
修复建议:基于用户session_id或者用户ID加接口限流,比如单个用户1分钟内最多允许提交3次生成请求。缺少通道订阅的权限校验
你目前的LongRunningRequestsChannel的subscribed方法仅依赖session_id生成通道名,没有校验当前连接的用户是否有权限订阅该通道;同时connection.rb里的身份验证逻辑是空实现,如果没补全的话,攻击者可以批量建立虚假连接,占用Action Cable的连接资源。
修复建议:订阅通道时校验session_id的合法性,补全Action Cable连接的身份校验逻辑,避免未授权的连接建立。下载链接存在敏感数据泄露风险
如果你生成的PDF包含用户敏感数据,要注意两点:- 存储PDF的云存储桶不要设置为公开可访问,最好生成带过期时间的签名下载链接,避免链接泄露后所有人都可以访问敏感文件。
- 如果用户的session_id被盗,攻击者可以订阅对应的通道拿到用户的PDF下载链接,建议针对每个生成任务额外加一次性的访问鉴权token。
前端代码存在变量污染风险
前端JS代码中downloadUrl、requestButtonId等变量没有用let/const声明,直接成为全局变量,容易被页面内的其他恶意脚本篡改,导致用户跳转到恶意下载地址。
修复建议:给所有局部变量加上const声明,避免变量泄露到全局作用域。PDF生成环节的输入过滤缺失
如果你的PDF内容包含用户提交的自定义内容,没有做过滤的话可能会导致PDF内嵌入恶意脚本,用户下载打开后触发执行。
修复建议:生成PDF前对所有用户输入的内容做转义过滤,避免注入恶意内容。
内容的提问来源于stack exchange,提问作者Yoko

