4. 授权与访问控制漏洞:通配符订阅滥用、Topic权限划分不当、超级用户权限过大
授权与访问控制,说白了就是决定「谁可以干什么」。MQTT 的 Topic 结构天然是树形的,这给了我们很大的灵活性,但也埋下了不少坑。我见过太多项目,因为权限没管好,整个系统就像没锁门的仓库。
这一章,我们重点聊三个最常出问题的地方:通配符订阅、Topic 权限划分,还有超级用户。嗯,咱们一个一个来看。
4.1 通配符订阅滥用
MQTT 的通配符 +(单层)和 #(多层)本来是为了方便订阅,但用不好就是灾难。
举个例子。你有个智能家居系统,每个房间的传感器数据放在 house/room1/temp、house/room2/temp 这样的 Topic 下。如果某个房间的客户端订阅了 house/+/temp,它就能看到所有房间的温度。这还算轻的。
我曾经在一个项目中遇到过,某个设备订阅了 #,结果把整个系统的内部状态、OTA 升级指令、甚至管理员心跳包全收走了。你想想看,这要是被恶意利用,后果不堪设想。
4.1.1 通配符滥用的典型场景
| 场景 | 订阅 Topic | 风险等级 | 说明 |
|---|---|---|---|
| 全局监听 | # |
极高 | 接收所有消息,包括系统级 Topic |
| 跨租户窥探 | tenant/+/data |
高 | 可访问其他租户的数据 |
| 越级控制 | +/device/cmd |
高 | 可能向非授权设备发送指令 |
| 日志泄露 | system/log/# |
中 | 暴露系统运行日志 |
4.1.2 防护措施
- 最小通配符原则:非必要不使用
#,能用+就别用#。 - 白名单订阅:在 Broker 端配置允许订阅的 Topic 列表,拒绝通配符的「越界」行为。
- 动态 ACL 检查:每次订阅请求都校验客户端身份与 Topic 的匹配关系。
$ 开头的系统 Topic,同时限制 # 只能由运维管理端使用。
4.2 Topic 权限划分不当
Topic 权限划分,核心是「谁可以发布,谁可以订阅」。很多系统只做了简单的用户名密码认证,但 Topic 级别的权限控制却形同虚设。
我见过一个工业 IoT 项目,所有设备都用同一个凭证连接 Broker,然后通过 Topic 前缀来区分功能。结果呢?一个温度传感器居然可以发布到 actuator/valve/ctrl 这个 Topic 上。这不是乱套了吗?
4.2.1 权限划分的常见错误
- 所有设备共享同一个凭证:无法区分设备身份,权限控制无从谈起。
- Topic 命名与权限脱钩:Topic 结构设计得很好,但 ACL 规则没跟上。
- 发布与订阅权限混为一谈:允许设备订阅某个 Topic,却不小心也允许它发布到该 Topic。
- 缺乏层级继承:父 Topic 的权限没有正确下放到子 Topic。
4.2.2 正确的权限划分模型
我建议采用「设备类型 + 设备 ID + 功能域」的三层 Topic 结构,配合细粒度的 ACL。
# Topic 结构示例
sensor/{device_id}/temp # 温度传感器只发布
actuator/{device_id}/valve # 执行器只订阅
admin/{device_id}/config # 管理端可发布和订阅
# ACL 规则示例(以 Mosquitto 为例)
# 允许传感器发布自己的温度数据
user sensor_001
topic write sensor/sensor_001/temp
# 允许执行器订阅自己的控制指令
user actuator_001
topic read actuator/actuator_001/valve
# 禁止传感器订阅任何 actuator Topic
user sensor_001
topic deny read actuator/#
4.3 超级用户权限过大
超级用户(Super User)在 MQTT 里通常意味着「不受 ACL 限制」。这个角色本意是给管理员用的,但很多系统把它用滥了。
我记得有一次做安全审计,发现某个 Broker 上 80% 的客户端都配置了超级用户权限。问运维为什么,他说「这样省事,不用配 ACL 了」。你想想看,这跟把公司大门钥匙发给每个员工有什么区别?
4.3.1 超级用户滥用的后果
- 权限失控:超级用户可以订阅任何 Topic,包括其他租户的敏感数据。
- 审计困难:所有操作都归到超级用户头上,出了问题根本查不到是谁干的。
- 攻击面扩大:一旦某个超级用户凭证泄露,攻击者就能控制整个 Broker。
4.3.2 超级用户的使用规范
| 角色 | 是否应使用超级用户 | 替代方案 |
|---|---|---|
| Broker 管理员 | 是(仅限运维操作) | 使用独立凭证,操作后立即禁用 |
| 普通设备 | 否 | 使用设备级凭证 + 细粒度 ACL |
| 后端服务 | 否 | 使用服务账号 + 最小权限原则 |
| 调试工具 | 临时可用 | 调试完成后立即撤销权限 |
4.4 授权与访问控制的整体架构
下面这张图,是我个人习惯用的授权与访问控制架构。它把认证、授权、审计三个环节串了起来。
4.5 实战建议
说了这么多,最后给几个落地建议。
- Topic 设计阶段就考虑权限:别等系统上线了再补 ACL,那时候改起来成本很高。
- 默认拒绝:ACL 的默认策略应该是拒绝所有,然后按需开放。
- 定期审计:我建议每个月跑一次权限审计脚本,检查有没有「越权」的订阅或发布。
- 超级用户凭证单独管理:不要写在配置文件里,用密钥管理服务(KMS)来托管。
#,如果成功了,说明 ACL 配置有问题。这个「自检」习惯帮我发现过好几次配置遗漏。
授权与访问控制,说白了就是「把门看好」。通配符别乱用,权限别乱给,超级用户别乱开。做到这三点,你的 MQTT 系统至少能挡住 80% 的权限相关攻击。