Node.js泄漏路径信息,如何解决?

时间:2012-05-09 18:17:48

标签: security node.js

我有一个运行的网络服务器...如果我从另一台服务器卷曲。这样的事情:

curl http://myserver.com/../../../../../etc/rsyslog.conf

然后我可以看到服务器信息。

这是一个已知问题吗?


UPDATE 这是我的服务器代码:

app = express.createServer(
            gzip.staticGzip(__dirname + '/public', {maxAge:5000 }),
            express.cookieParser(),
            express.bodyParser()

        );

得到了这样的修复:

var urlSecurity = function () {
    return function (req, res, next) {
        if (req.url.indexOf('../') >=0) {
            res.send('<div>Server Error</div>' , 500);
        } else if (req.url.indexOf('/..') >=0) {
            res.send('<div>Server Error</div>' , 500);
        } else {
            next();
        }
    }
}
app = express.createServer(
urlSecurity (),
            gzip.staticGzip(__dirname + '/public', {maxAge:5000 }),
            express.cookieParser(),
            express.bodyParser()

        );

这还不错吗?

4 个答案:

答案 0 :(得分:2)

您的计划存在严重的安全漏洞。立即修复它。

我从所呈现的症状中得出的最佳猜测是,你正在做类似的事情:

http.createServer(function (request, response) {
  var file = path.resolve('/path/to/files', request.url)
  fs.createReadStream(file).pipe(response)
})

这是非常不明智的!始终清理用户输入。在这种情况下,这很容易:

http.createServer(function (request, response) {
  var requestedFile = path.join('/', request.url);
  var file = path.join('/path/to/files', requestedFile)
  fs.createReadStream(file).pipe(response)
})

首先,我们path.join将请求的网址'/'发送到..。这将消除任何path.join恶作剧,使其更卫生。然后,我们path.join到我们的网址上。

为什么在这种情况下使用path.resolve而不是path.join?因为/只是加入路径部分而不是解析它们,所以领先的{{1}}不会产生任何不良影响。

答案 1 :(得分:2)

立即修复后,我做了很多测试。我确认以下内容:

主要不是节点问题。导致问题的是gzippo模块。 Gzippo 0.1.3导致了这个问题。 0.1.4没问题。不知道为什么会这样。但最好不要使用旧版本的gzippo。

答案 2 :(得分:0)

最简单的解决方案是insecureFileName.split('/').pop()将始终只返回fileName。

'index.html'.split('/').pop() => 'index.html'
'../../../index.html'.split('/').pop() => 'index.html'

答案 3 :(得分:0)

我使用以下命令清除用户文件名

path.basename(filename);

例如:

const path = require('path');
let filename = '../../../../../../../etc/passwd';
filename = path.basename(filename); // 'passwd'
let pathToFile = path.join('/path/from/config/to', filename);
console.log(pathToFile); // 'path/from/config/to/passwd'