干货:Node.js 安全说明书

1. 数据验证 – 永远不要信任你的用户

来自用户输入或其他系统的数据,你都必须要进行验证。否则,这会对当前系统造成威胁,并导致不可想象的安全漏洞。现在,让我们学习如何验证Node.js中的传入数据。你可以使用名为 validator 的模块来执行数据验证。 例如:


  1. const validator = require('validator'); 
  2. validator.isEmail('foo@bar.com'); //=> true 
  3. validator.isEmail('bar.com'); //=> false 

另外,你也可以使用 joi 模块来进行数据和模型的验证,例如:


  1. const joi = require('joi'); 
  2.   try { 
  3.     const schema = joi.object().keys({ 
  4.       name: joi.string().min(3).max(45).required(), 
  5.       email: joi.string().email().required(), 
  6.       password: joi.string().min(6).max(20).required() 
  7.     }); 
  8.  
  9.     const dataToValidate = { 
  10.         name"Shahid"
  11.         email: "abc.com"
  12.         password"123456"
  13.     } 
  14.     const result = schema.validate(dataToValidate); 
  15.     if (result.error) { 
  16.       throw result.error.details[0].message; 
  17.     }     
  18.   } catch (e) { 
  19.       console.log(e); 
  20.   } 

2. SQL注入攻击

SQL注入可以让恶意用户通过传递非法参数,来篡改SQL语句。下面是一个例子,假设你写了这样一个SQL:


  1. UPDATE users  
  2. SET first_name="' + req.body.first_name + '" WHERE id=1332; 

在正常情况下,你希望这次查询应该是这样的:


  1. UPDATE users  
  2. SET first_name = "John" WHERE id = 1332; 

但是现在,如果有人将 first_name 的值按下面这种方式传递:


  1. John", last_name="Wick";  

这时,你的SQL语句就会变成这样:


  1. UPDATE users  
  2. SET first_name="John", last_name="Wick"–" WHERE id=1001; 

你会看到, WHERE 条件被注释掉了,这次更新会将整张表所有用户的 first_name 改成 John , last_name 改成 Wick 。这下,你闯祸了!

如何避免SQL注入

避免SQL注入攻击最有效的办法就是将输入数据进行过滤。你可以对每一个输入数据逐一进行验证,也可以用参数绑定的方式验证。开发者们最常用的就是参数绑定的方式,因为它高效而且安全。

如果你在使用一些比较流行的ORM框架,例如sequelize、hibernate等等,那么框架中就已经提供了这种数据验证和SQL注入保护机制。

如果你更喜欢依赖数据库模块,例如 mysql for Node ,那么你可以使用数据库提供的过滤方法。下面代码是使用 mysql for Node 的一个例子:


  1. var mysql = require('mysql'); 
  2. var connection = mysql.createConnection({ 
  3.   host     : 'localhost'
  4.   user     : 'me'
  5.   password : 'secret'
  6.   database : 'my_db' 
  7. }); 
  8.  
  9. connection.connect(); 
  10.  
  11. connection.query( 
  12.     'UPDATE users SET ?? = ? WHERE ?? = ?'
  13.     ['first_name',req.body.first_name, ,'id',1001], 
  14.     function(err, result) { 
  15.     //… 
  16. }); 

?? 的地方被字段名称替换, ? 的地方被字段值替换,这样就保证了输入值的安全性。

你也可以使用存储过程来提高安全级别,但是由于缺乏可维护性,开发人员倾向于避免使用存储过程。

同时,你还应该执行服务器端的数据验证。 但我不建议你手动验证每个字段,可以使用 joi 等模块来解决这个问题。

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章