Node.js - 安全地从字符串中执行代码

时间:2015-05-13 12:39:28

标签: javascript node.js

我目前正在编写MongoDB学习页面,该页面在后端使用Node.js和Express。前端用户的一个可能性是:将他们自己的查询发送到数据库并将结果(或错误)返回到前端。他们应该在数据库中找到/ insert / update / -access。

查询将作为字符串传输。伪代码:客户端 - &gt; <input type='text'> - &gt; JSON - &gt; Node.js-Server - &gt;执行查询 - &gt; res.send(error/result)

首先Google-和Stackoverflow-seaches显示,eval()正是我在这种情况下所需要的。但它也表明,eval()非常危险。我想象的东西 var string = "var fs = require('fs'); fs.createReadStream(..., function(...){ res.send(...)};"或更糟。一个聪明的黑客肯定能猜到MongoDB-Learning-Page基于Node.js,可以轻松验证使用过的框架和数据库驱动程序。

你会建议做什么?是否有一种沙箱只允许访问数据库和res,req - 对象?

2 个答案:

答案 0 :(得分:0)

我接近这个的方法是在代码中为正在发送的字符串创建一个抽象层,而根本不使用eval。通过Web浏览器(客户端)为最终用户提供直接执行的能力本质上是危险的,永远不应该这样做。

而是使用javascript string functionsregular expressions创建字符串解析器。

您的应用程序将收到正在发送的字符串,并解析它的有效性和安全性,您甚至可以在客户端对此类字符串进行实时审核,并在最终用户出现格式错误时提供最终用户提示或错误串。然后,您可以在解析方面制定适当的操作。

在编程和数据库中,这被称为CRUD的脚手架(创建,读取,更新,删除)。创建这个抽象层可能需要更多的工作,但为了保护数据库的目的,它的收益是值得的。从某种意义上说,您创建自己的沙箱,因为最终,您可以运行的唯一数据库执行代码就是您在抽象中扩展的内容。

以下是此方法中psuedo-code的重构:

Pseudo-Code: Client --> <input type='text'> --> Node.js-Server -->
Sanitize & Parse String Data into a safely executable query --> 
Execution of query --> res.send(error/result).`

答案 1 :(得分:0)

编辑:显然,学习页面是关于 MongoDB的,而不是由它支持。不过,无论如何,限制访问的第一个想法仍然适用。但如果需要只有一种“试用”环境,你可以使用像minimongo这样的客户端MongoDB实现

如果您确实想发送数据库查询,则至少可以限制Express应用程序使用的MongoDB用户的权限。这可以被认为是一种沙盒 - 你可以例如仅限用户READ操作(当然这不是您想要的)。

我建议分析您是否真的需要前端完整数据库查询的强大功能。如果你是只需要使用集合上的ID就可以使用简单的RESTful Web服务和以下请求来获取CRUD:

GET /{collection}/{id},...

如果需求变得更加复杂,那么您的API当然会变得更加复杂。

如果您想公开各种MongoDB功能,您应该查看MongoDB HTTP Interface的实现。

NodeJS实现是Crest,可能正是您正在寻找的。