当前位置: 首页 > 知识库问答 >
问题:

防止Node.js中的SQL注入

步博厚
2023-03-14

是否可以像PHP准备语句那样防止SQL注入Node.js(最好是使用模块)。

如果是,怎么做?如果不是,有哪些例子可以绕过我提供的代码(见下文)。

某些上下文:

我正在使用node-mysql模块制作一个具有由node.js+MySql组成的后端堆栈的web应用程序。从可用性的角度来看,这个模块很棒,但是它还没有实现类似于PHP准备好的语句的东西(尽管我知道它在todo上)。

根据我的理解,PHP对准备好的语句的实现,特别是对防止SQL注入有很大的帮助。不过,我担心我的Node.js应用程序可能会受到类似的攻击,即使默认提供了字符串转义(如下面的代码片段所示)。

node-mysql似乎是Node.js最流行的mysql连接器,所以我想知道其他人可能会做些什么(如果有的话)来解释这个问题--或者它是否是Node.js的一个问题(不知道这怎么会不是,因为涉及到用户/客户端输入)。

我是否应该暂时切换到node-mysql-native,因为它确实提供了准备好的语句?我对这样做犹豫不决,因为它似乎不像node-mysql那样活跃(尽管那可能只是意味着它是完整的)。

下面是一段用户注册代码,它使用了sanitizer模块,以及Node-MySQL准备好的类似语句的语法(正如我前面提到的,它可以进行字符转义),分别防止跨站点脚本和sql注入:

// Prevent xss
var clean_user = sanitizer.sanitize(username);

// assume password is hashed already
var post = {Username: clean_user, Password: hash};

// This just uses connection.escape() underneath
var query = connection.query('INSERT INTO users SET ?', post,
   function(err, results)
   {
       // Can a Sql injection happen here?
   });

共有3个答案

左丘宜然
2023-03-14

关于测试您正在使用的模块是否安全,有几条路可以选择。我将讨论每种方法的利弊,这样你就可以做出更明智的决定。

当前,您正在使用的模块没有任何漏洞,但是,这通常会导致错误的安全感,因为您正在使用的模块/软件包当前很可能存在一个漏洞,并且在供应商应用修复/修补程序之前,不会向您发出问题警报。

>

  • 要及时了解漏洞,您需要关注邮件列表、论坛、IRC和其他与黑客攻击有关的讨论。支持:你经常会意识到库中的潜在问题,在供应商收到警告或发布修复程序/补丁来弥补其软件的潜在攻击渠道之前。Con:这会耗费大量的时间和资源。如果你真的走这条路,一个使用RSS提要、日志解析(IRC聊天日志)的bot和(或)一个使用关键短语(在本例中是node-mysql-native)和通知的web scrapper可以帮助减少花在这些资源上的时间。

    创建fuzzer,使用fuzzer或其他漏洞框架(如metasploit、sqlMap等)来帮助测试供应商可能没有找到的问题。赞成:这可以证明是一种确保您正在实现的模块/软件是否安全的可接受的水平的可靠的方法,以供公众访问。Con:这也会变得耗费时间和成本。另一个问题来自误报以及对存在问题但未被注意到的结果进行未受过教育的审查。

    真正的安全性和应用程序的安全性通常非常耗时和耗费资源。管理人员总会使用一个公式来确定执行上述两个选项的成本效益(人力、资源、时间、薪酬等)。

    无论如何,我知道这不是一个‘是’或‘否’的答案,可能一直希望,但我不认为任何人可以给你,直到他们执行一个软件的分析问题。

  • 后化
    2023-03-14

    库在自述文件中有一节是关于转义的。它是JavaScript原生的,所以我不建议切换到Node-MySQL-Native。该文档说明了转义的指导原则:

    编辑:node-mysql-native也是一个纯JavaScript解决方案。

    • 数字保持不变
    • 布尔值转换为true/false字符串
    • 日期对象转换为YYYY-MM-DD HH:II:SS字符串
    • 缓冲区转换为十六进制字符串,例如x'0fa5'
    • 字符串被安全转义
    • 数组转换为列表,例如['a','b']转换为'a','b'
    • 嵌套数组转换成分组列表(用于批量插入),例如[['a','b'],['c','d']]转换成('a','b'),('c','d')
    • 对象被转换为key='val'对。嵌套对象转换为字符串。
    • 未定义/转换为
    • nan/infinity保持原样。MySQL不支持这些,并且尝试将它们作为值插入将触发MySQL错误,直到它们实现支持。

    这允许您执行如下操作:

    var userId = 5;
    var query = connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
      //query.sql returns SELECT * FROM users WHERE id = '5'
    });
    

    还有这一点:

    var post  = {id: 1, title: 'Hello MySQL'};
    var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
      //query.sql returns INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
    });
    

    除了这些函数外,您还可以使用转义函数

    connection.escape(query);
    mysql.escape(query);
    

    转义查询标识符:

    mysql.escapeId(identifier);
    

    作为对你对准备好的发言的评论的答复:

    从可用性的角度来看,这个模块很棒,但是它还没有实现类似于PHP的准备好的语句的东西。

    准备好的语句位于此连接器的todo列表上,但此模块至少允许您指定与准备好的语句非常相似的自定义格式。以下是自述文件中的一个示例:

    connection.config.queryFormat = function (query, values) {
      if (!values) return query;
      return query.replace(/\:(\w+)/g, function (txt, key) {
        if (values.hasOwnProperty(key)) {
          return this.escape(values[key]);
        }
        return txt;
      }.bind(this));
    };
    

    这将更改连接的查询格式,以便您可以使用如下所示的查询:

    connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
    //equivalent to
    connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");
    
    郎鸿
    2023-03-14

    node-mysql库在使用时自动执行转义,就像您已经在做的那样。参见https://github.com/felixge/node-mysql#escaping-query-values

     类似资料:
    • 问题内容: 是否有可能以与PHP具有防止它们攻击的Prepared语句相同的方式来防止在Node.js(最好是使用模块)中进行SQL注入。 如果是这样,怎么办?如果没有, 那么有哪些示例 可以绕过我提供的代码(请参见下文)。 一些上下文: 我正在使用node-mysql模块制作一个包含Node.js+MySql的后端堆栈的Web应用程序。从可用性的角度来看,该模块很棒,但是它还没有实现类似于PHP

    • 所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。具体来说,它是利用现有应用程序,将(恶意)的 SQL 命令注入到后台数据库引擎执行的能力,它可以通过在 Web 表单中输入(恶意)SQL 语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行 SQL 语句。比如先前的很多影视网站泄露 VI

    • 本文向大家介绍Pyhton中防止SQL注入的方法,包括了Pyhton中防止SQL注入的方法的使用技巧和注意事项,需要的朋友参考一下 注意,上面的SQL字符串与后面的tuple之间的分隔符是逗号,平时拼写SQL用的是%。 如果按照以下写法,是容易产生SQL注入的: 这个和PHP里的PDO是类似的,原理同MySQL Prepared Statements。 Python Using the Pytho

    • 本文向大家介绍Mybatis防止sql注入的实例,包括了Mybatis防止sql注入的实例的使用技巧和注意事项,需要的朋友参考一下 sql注入大家都不陌生,是一种常见的攻击方式,攻击者在界面的表单信息或url上输入一些奇怪的sql片段,例如“or ‘1'='1'”这样的语句,有可能入侵参数校验不足的应用程序。所以在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性很高的应用中,比如银行

    • 问题内容: 我有一个现有的代码,其中应用程序根据很多条件生成不同的sql并通过hibernate会话createSQLQuery()执行它们。在这里,这些参数与作为普通字符串替换驻留在java类中的sql字符串相连接。现在的问题是,我需要防止sql注入。因此,为此,我必须使用getNamedQuery()并绑定参数,以便hibernate将处理特殊字符。但是问题在于将字符串sql的字符串移动到xm

    • 注意:但凡是sql注入漏洞的程序,都是因为程序要接受来自客户端用户输入的变量或URL传递的参数,并且这个变量或参数是组成sql语句的一部分,对于用户输入的内容或传递的参数,我们应该要时刻保持警惕,这是安全领域里的【外部数据不可信任】的原则,纵观web安全领域的各种攻击方式,大多数都是因为开发者违反了这个原则而导致的,所以自然能想到,就是变量的检测、过滤、验证下手,确保变量是开发者所预想的。 1、检