真正有效的限制是让“能查”和“能导出”走不同权限路径,因用户只要能连库并认证,即可用find等命令拉取全量数据;禁用mongodump或限制其文件权限无效,因客户端工具非必需,且find本身支持流式导出。

不能靠禁用 mongosh 或删掉 mongodump 来阻止导出 —— 用户只要能连上数据库,就能用 find 拉走全部数据。真正有效的限制,是让“能查”和“能导出”走完全不同的权限路径。
为什么禁止 mongodump 文件权限没用
常见误解是 chmod -x /usr/bin/mongodump 或改 owner 就能防导出。问题在于:
-
mongodump只是客户端工具,不执行它,用户仍可用db.collection.find().toArray()在mongosh里手动遍历拉取全量数据 - Python +
pymongo、Node.js +mongodb驱动都能实现等效导出逻辑,且不受本地二进制文件权限约束 - 即使禁了所有 shell 工具,只要 MongoDB 端口(如 27017)对用户开放,且认证通过,
find命令本身已具备完整读取能力
内置 read 角色默认允许哪些导出类操作
授予 { role: "read", db: "myapp" } 后,用户实际能做的远不止“看一眼”:
-
find、aggregate(不含$out、$merge)、count、distinct全部放行 -
listCollections和listIndexes若未显式拒绝,也会默认可用(取决于是否授了read所在库的配套权限) - 关键点:
find返回游标后,客户端可无限次getMore,等价于流式导出 —— 这不是 bug,是协议设计
真正可控的防线:用自定义角色禁用高危动作
MongoDB 不提供“禁止导出”开关,但可以收窄到只留 find 必需的最小动作集。例如:
use admin
db.createRole({
role: "findOnly",
privileges: [{
resource: { db: "myapp", collection: "orders" },
actions: ["find"]
}],
roles: []
})这个角色生效的关键细节:
- 必须在
admin库创建,否则无法被授予 -
actions列表里**不能包含**listCollections、listIndexes、collStats—— 否则用户能枚举集合结构,辅助构造更精准的find - 不授
dbStats或serverStatus,防止通过统计信息反推数据规模 - 连接后执行
db.runCommand({connectionStatus: 1}),确认authInfo.roles中只出现findOnly,且无其他隐式继承角色
绕过风险与运维提醒
即使角色定义干净,仍有两个常被忽略的出口:
- 如果用户有
read权限在config或local库(哪怕只是只读),可能读到分片路由表、oplog 时间戳等元信息,间接辅助批量提取 -
find命令本身支持limit、skip、sort,配合脚本循环即可模拟mongodump行为 —— 这不是权限漏洞,而是设计使然;唯一缓解方式是网络层限速或连接数限制(如maxIncomingConnections)
所以,“只让执行 find” 的本质,是接受用户能读取授权集合全部内容的事实,而把防线前移到认证源头:确保该用户连不上其他库、看不到其他集合、拿不到任何元数据。剩下的,就不是 MongoDB 权限系统该管的事了。

















