我有一个运行的网络服务器...如果我从另一台服务器卷曲。这样的事情:
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()
);
这还不错吗?
答案 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'