通过堆栈跟踪暴露信息¶
ID: js/stack-trace-exposure
Kind: path-problem
Security severity: 5.4
Severity: warning
Precision: very-high
Tags:
- security
- external/cwe/cwe-209
- external/cwe/cwe-497
Query suites:
- javascript-code-scanning.qls
- javascript-security-extended.qls
- javascript-security-and-quality.qls
软件开发人员经常在错误消息中添加堆栈跟踪,作为调试辅助工具。每当最终用户遇到该错误消息时,开发人员可以使用堆栈跟踪来帮助识别如何解决问题。特别是,堆栈跟踪可以告诉开发人员更多关于导致故障的事件序列的信息,而不仅仅是错误发生时软件的最终状态。
不幸的是,相同的信息对攻击者也很有用。堆栈跟踪中的函数名称序列可以揭示应用程序的结构以及它依赖的任何内部组件。此外,堆栈跟踪顶部的错误消息可能包含诸如服务器端文件名和应用程序依赖的 SQL 代码之类的信息,使攻击者能够微调随后的注入攻击。
建议¶
向用户发送更通用的错误消息,以揭示更少的信息。要么完全抑制堆栈跟踪,要么仅在服务器上记录堆栈跟踪。
示例¶
在以下示例中,捕获了一个异常,并将它的堆栈跟踪作为 HTTP 响应的一部分发送回远程用户。因此,用户能够看到详细的堆栈跟踪,其中可能包含敏感信息。
var http = require('http');
http.createServer(function onRequest(req, res) {
var body;
try {
body = handleRequest(req);
}
catch (err) {
res.statusCode = 500;
res.setHeader("Content-Type", "text/plain");
res.end(err.stack); // NOT OK
return;
}
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.setHeader("Content-Length", body.length);
res.end(body);
}).listen(3000);
相反,堆栈跟踪应该仅在服务器上记录。这样,开发人员仍然可以访问和使用错误日志,但远程用户将看不到这些信息。
var http = require('http');
http.createServer(function onRequest(req, res) {
var body;
try {
body = handleRequest(req);
}
catch (err) {
res.statusCode = 500;
res.setHeader("Content-Type", "text/plain");
log("Exception occurred", err.stack);
res.end("An exception occurred"); // OK
return;
}
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.setHeader("Content-Length", body.length);
res.end(body);
}).listen(3000);