db.eval()必须禁用,因其允许在服务端执行任意javascript代码,存在严重安全风险:可耗尽cpu、意外关库等;官方自3.2起弃用,4.0+默认禁用,且需通过配置security.javascriptenabled: false并重启生效。

db.eval() 为什么必须禁用
db.eval() 允许在服务端直接执行任意 JavaScript 字符串,等同于把一个可执行沙盒交到调用者手上。它不校验输入、不隔离作用域、不审计上下文——只要连接上数据库,就能执行 db.eval("while(true){}"); 搞垮 CPU,或 db.eval("db.getSiblingDB('admin').runCommand({shutdown:1})"); 直接关库。MongoDB 官方早在 3.2 版本起就标记该函数为 deprecated,4.0+ 版本默认禁用,但旧配置迁移或未显式关闭时仍可能残留风险。
如何确认 javascriptEnabled 是否已关闭
连入 MongoDB shell 后执行:
db.runCommand({ getParameter: 1, javascriptEnabled: 1 })如果返回 {"javascriptEnabled": true, "ok": 1},说明仍开启;若报错 no such command 或返回 false,大概率已禁用。注意:该命令本身不触发 JS 执行,是安全的探测方式。
禁用 javascriptEnabled 的实操步骤
编辑 MongoDB 配置文件(通常是 /etc/mongod.conf 或 C:\MongoDB\mongod.conf),在 security 区块下添加或修改:
security: javascriptEnabled: false
- 必须重启
mongod进程才生效,仅重载配置无效 - 若配置中已有
security:但无javascriptEnabled字段,默认值取决于 MongoDB 版本(3.6+ 默认false,但显式写出来更可靠) - 不要依赖
--noscripting启动参数——它已被弃用,且在 systemd 或 Windows 服务模式下难以稳定传递
禁用后还要防哪些漏网之鱼
javascriptEnabled: false 只禁用 db.eval()、$where、mapReduce 等显式 JS 执行入口,但以下场景仍可能绕过或引发类似风险:
-
$where查询仍会报错,但错误信息可能泄露集合结构(如字段名),建议配合logLevel: 0降低日志敏感度 - 若启用了
mongo-express等 Web 管理工具,其内部可能封装了 eval 类逻辑,需单独检查其配置中的enableJavaScript开关 - 通过驱动调用
eval命令(如 PyMongo 的db.command("eval", ...))会被直接拒绝,但部分旧版驱动可能静默降级——务必升级到对应 MongoDB 版本兼容的驱动
真正难缠的是那些没被明确标记为“JS 执行”的地方:比如聚合管道里的 $function(4.4+ 引入),它同样支持内联 JS,且默认不受 javascriptEnabled 控制——必须单独用 setParameter 关闭:db.adminCommand({ setParameter: 1, disableJavaScript: true })。











