数据库暴露:最佳实践

时间:2013-10-06 18:21:54

标签: node.js security angularjs express neo4j

我是一个相对较新的网络程序员,我目前正在开展我的第一个重大项目。我正在使用angular,express(在节点之上)和图形数据库neo4j。现在,我正在尝试确定最佳(在安全性和速度优化方面)方式来设置Web应用程序与数据库的交互方式。

现在我觉得我有点盲目地进入这个问题 - 我正在寻找的是最佳实践指南,需要考虑的安全问题,以及在设置时要注意的任何其他相关建议或陷阱一个Web应用程序后端。

为了更具体一点,我会告诉你我现在如何设置路线。以下是app.js文件中设置的路径。

    //match database query functions
function dataQuery(req, res) {
    var func = database[req.param('query')];
    func(req, res);
}
    //match database create functions
function dataCreate(req, res) {
    var func = database[req.param('create')];
    func(req, res);
}
//handle data queries
app.get('/query/:query', dataQuery);

//handle adding new content
app.post('/create/:create', dataCreate)

基本上我已经设置好了,这样我就可以POST或GET到一个刚刚执行功能的URL。我基本上命名我想在url:/ query / theNameOfTheFunction中运行的函数。然后,这些函数将构建一个密码查询(neo4j的查询语言),利用请求中的信息与数据库交互或处理诸如添加用户上传图像之类的事情。

示例:创建内容(URL:/ query / createContent)

exports.createContent = function (req, res) {

    var content = JSON.parse(req.query.content);
    var query = ("CREATE (n:Content {Title: {title}, URL: {url}, Description: {description}, Source: {source}, Links: {links}, Value: {valueStatement} })");

    query = query.replace("{title}", "\"" + content.title + "\"");
    query = query.replace("{url}", "\"" + content.url + "\"");
    query = query.replace("{description}", "\"" + content.description + "\"");
    query = query.replace("{source}", "\"" + content.source + "\"");
    query = query.replace("{links}", "\"" + content.links + "\"");
    query = query.replace("{valueStatement}", "\"" + content.valueStatement + "\"");

   db.query(query, function (err, results) {
       if (err) {res.send()};
       res.send();
   });
}

这里我有一个查询模板,只需使用replace。

删除用户生成的信息

示例:将图像添加到服务器(URL:/ create / addImage)

exports.addImage = function (req,res) {
    var url = req.query.url;
    var fileName = req.query.fileName;

    console.log(req.query);
    request(url).pipe(fs.createWriteStream("./img/submittedContent/" + fileName));
    res.send();
}

似乎这种方法可能不是很容易扩展,但我不确定如何在服务器端最好地组织代码。

我想提到的另一个具体例子是以下案例。查询本身很复杂,我现在已经将它创建到客户端(查询查找与用户选择的条款相关的内容,并相应地改变长度)。客户端发送创建的查询,并将其传递给neo4j api。显然,这里存在一些问题 - 如果用户能够定义查询,他们可以对数据库执行任何操作(删除所有内容或其他内容)。我不清楚某人是如何准确地这样做的,但这看起来确实可行。

exports.getContent = function (req, res) {
    var query = req.query.query;

        //would checking for black/white list key terms be enough security? (remove, create, set, etc)

    db.query(query, function (err, results) {
        if (err) {throw err};
        res.send(results);
    });
}

我是否完全错了这个东西?我从来没有得到正式的服务器端脚本介绍,我只读了我读过的东西。我想以'正确的方式'做到这一点,但我需要先知道那是什么方式......

1 个答案:

答案 0 :(得分:3)

只是一些随机指针:

  • 我建议设置RESTful Web API来处理Angular和数据库之间的通信;不必自己发明所有路线就麻烦了,这也意味着你可以使用像Restangular(对于客户端)和Restify(对于服务器)这样的优秀库来处理通信; < / LI>
  • 不确定您使用的是哪个Neo4j驱动程序,但我确信它们都支持参数化查询,这意味着您无需执行所有query.replace()次调用(see);
  • 取决于可能上传的图像数量,将它们存储在文件系统中可能没问题,尽管您永远不应该信任传递的文件名;如果你想要更多的可扩展性,你可以考虑使用MongoDB的GridFS;
  • 永远不要相信从客户端传递的查询要在服务器上执行;如果你可以在客户端构建查询,你也可以在服务器端构建它,并将信息从客户端传递到服务器(同样,使用参数化查询);