接口鉴权通过,对象却属于别人:LimeSurvey 跨问卷授权缺陷解析

接口鉴权通过,对象却属于别人:LimeSurvey 跨问卷授权缺陷解析

背景与时间线

报告方 Fluid Attacks记录:2026 年 9 月 23 日 发现,24 日联系厂商,28 日确认、修复并公开。GitHub CVE 记录于 9 月 29 日 收录 CVE-2026-97685 ,该条目标明 Unreviewed,不能当作 GitHub 已审核结论。

证据来自报告方披露、公开 CVE 描述及项目修复提交。研究者验证版本为 Community Edition 7.3.0。本次没有核清最低修复发布版本,不能凭补丁已合并推断某个发行包必然安全。

技术原理:授权对象和写入对象必须是同一个

已确认链路是:接口针对 URL 中的问卷检查权限,但后续根据请求中的全局题目或答案 ID 查找对象,没有验证对象属于被授权问卷。具备创建问卷权限的已认证用户,可能借自己的合法问卷上下文修改其他问卷对象。

**工程分析:**问题不在于权限检查完全不存在,而在于权限检查的主语变了。代码读起来可能每一步都合理:先检查问卷,再查询题目,再执行更新。但这三步之间缺少关系约束。

更稳健的数据访问方式是把授权范围写进查询条件,而不是先全局查到对象再期望每个调用者记住补查。对于批量操作,还要保证一个非法对象不会在前面合法对象已经写入后才被发现。

校验层 需要证明的关系
用户与问卷 用户可以编辑该问卷
问卷与题目 题目确实属于该问卷
题目与答案 答案属于预期题目和问卷
批量操作 所有目标通过校验后再提交

影响范围与证据边界

本次披露证明跨问卷完整性风险,必要条件包含认证及相应操作权限。本文不将其扩大成匿名接管、任意 SQL 注入或 RCE。报告页的利用演示代表受控验证,不是现实攻击活动证明。

修复提交可用于代码核对,但部署团队仍需核验其是否包含在自己的发行包、容器镜像或下游回补中。在确认前,可评估限制相关 REST 修改功能和缩小创建、编辑权限范围,作为临时风险降低措施。

无害内存模型

python 复制代码
surveys = {10: {'owner': 'alice'}, 20: {'owner': 'bob'}}
questions = {101: {'survey': 10, 'text': 'A'},
             201: {'survey': 20, 'text': 'B'}}

def update(user, survey_id, changes):
    if surveys[survey_id]['owner'] != user:
        raise PermissionError('survey denied')
    # 全量校验在任何写入之前完成。
    for qid, text in changes:
        if qid not in questions or questions[qid]['survey'] != survey_id:
            raise PermissionError('question outside scope')
    for qid, text in changes:
        questions[qid]['text'] = text

try:
    update('alice', 10, [(101, 'new'), (201, 'wrong')])
except PermissionError:
    pass
assert questions[101]['text'] == 'A'
assert questions[201]['text'] == 'B'
update('alice', 10, [(101, 'valid')])
assert questions[101]['text'] == 'valid'
print('ownership and atomicity model passed')

示例不连接 LimeSurvey,也不构造真实请求。真实数据库中还需要事务与并发控制,避免校验后对象归属发生变化;单线程字典模型不具备这些保证。

研发与安全团队行动清单

P0:确认部署包含修复

记录当前版本和制品标识,追踪官方修复进入发行版本的情况。评估相关接口可达性和低权限账号范围。审计日志可检查用户、URL 问卷 ID、实际修改对象归属是否一致,但不要把一次合法跨对象管理操作直接判成攻击。

P1:测试关系,而非只测试角色

准备两个测试用户、两份问卷、分别归属的题目和答案,覆盖同租户不同所有者、不同问卷、混合批量以及不存在的 ID。每个拒绝测试都应确认数据未发生部分写入。

P2:约束下沉与审计对账

将授权上下文显式传入服务层,避免持久化层只接受裸全局 ID。数据库查询将范围作为条件,更新结果为零时区分无权限和不存在的内部处理,同时控制对外错误信息,避免泄露对象存在性。

安全团队可从控制器到仓储层追踪同一请求内的标识符:哪个被检查,哪个被修改,中间是否发生重新解析。这个方法适用于订单、项目、文档和多租户配置系统,但不意味着它们天然存在同类漏洞。

总结

授权必须跟着最终对象走。一次成功的入口鉴权不能自动覆盖后来从请求体解析出的所有全局 ID。把归属约束写进查询和事务,比在每个接口补零散判断更容易维护。

相关推荐
程序员-Benothing3 小时前
Linux安全加固指南:账号、权限、服务、审计基线
linux·运维·安全
数据库安全8 小时前
AI数据访问安全 |如何控制AI访问权限,防止越权
数据库·安全
2501_937767168 小时前
面向设计 / 研发部门:终端文件统一归档 + 服务器定时备份实践
运维·安全
珠海西格电力9 小时前
物联网(IoT)在零碳园区中的关键作用:万物互联与数据采集
大数据·人工智能·物联网·安全·系统架构·能源
沐梯子9 小时前
2026消防排烟风机厂家推荐:消防风机、排烟风机、厂房通风、建筑通风风机选型指南
系统安全
安教安全员通关宝10 小时前
【证书管理】安全员 C 证延续:条件、时间窗口与各省口径对照
安全
网易易盾12 小时前
直播话术合规改造:六类违规表述判定与改写规则
大数据·人工智能·安全
dk_tjy12 小时前
迪康加密系统技术解析:驱动层透明加密的机制、策略与工程权衡
运维·安全·网络安全·终端安全管理·数据防泄漏
龙亘川12 小时前
城市公共安全治理如何从“人海战术“走向“数据驱动“?
大数据·数据库·人工智能·安全·microsoft·智慧城市·数据可视化
合尘猫12 小时前
给 AI 客服加权限边界:12 项自查清单与一次越权测试
人工智能·安全·llm