Skip to content

Commit db1b708

Browse files
authored
Merge pull request #7547 from Countly/claude/strange-archimedes-c050c8
[security] Fix Fortify-flagged path traversal, XSS and info-leak issues
2 parents ea740f5 + 12a2681 commit db1b708

5 files changed

Lines changed: 25 additions & 15 deletions

File tree

api/utils/common.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,10 @@ common.returnMessage = function(params, returnCode, message, heads, noResult = f
14031403
else {
14041404
console.error("Output already closed, can't write more");
14051405
console.trace();
1406-
console.log(params);
1406+
// Don't dump the full params object — req.body/req.headers can
1407+
// contain credentials, session cookies, or other secrets. Log
1408+
// only the pathname (query string can carry api_key/auth_token).
1409+
console.log({pathname: params.urlParts && params.urlParts.pathname, apiPath: params.apiPath, qstringKeys: params.qstring && Object.keys(params.qstring)});
14071410
}
14081411
}
14091412
};
@@ -1485,7 +1488,10 @@ common.returnOutput = function(params, output, noescape, heads) {
14851488
else {
14861489
console.error("Output already closed, can't write more");
14871490
console.trace();
1488-
console.log(params);
1491+
// Don't dump the full params object — req.body/req.headers can
1492+
// contain credentials, session cookies, or other secrets. Log
1493+
// only the pathname (query string can carry api_key/auth_token).
1494+
console.log({pathname: params.urlParts && params.urlParts.pathname, apiPath: params.apiPath, qstringKeys: params.qstring && Object.keys(params.qstring)});
14891495
}
14901496
}
14911497
};

frontend/express/app.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -479,14 +479,16 @@ Promise.all([plugins.dbConnection(countlyConfig), plugins.dbConnection("countly_
479479
app.use(cookieParser());
480480
//server theme images
481481
app.use(function(req, res, next) {
482-
var urlPath = req.url.replace(countlyConfig.path, "");
482+
var urlPath = req.path.replace(countlyConfig.path, "");
483483
var theme = req.cookies.theme || curTheme;
484-
if (theme && theme.length && (req.url.indexOf(countlyConfig.path + '/images/') === 0 || req.url.indexOf(countlyConfig.path + '/geodata/') === 0)) {
485-
fs.exists(__dirname + '/public/themes/' + theme + urlPath, function(exists) {
486-
if (exists) {
487-
res.sendFile(__dirname + '/public/themes/' + theme + urlPath);
488-
}
489-
else {
484+
if (theme && theme.length && (req.path.indexOf(countlyConfig.path + '/images/') === 0 || req.path.indexOf(countlyConfig.path + '/geodata/') === 0)) {
485+
// Both `theme` (cookie) and `urlPath` (URL) are user-controlled.
486+
// Hand the relative path to res.sendFile with `root` set to
487+
// /public/themes — express normalizes the path and rejects any
488+
// `..` traversal before touching the filesystem. Missing files
489+
// surface via the error callback and fall through to next().
490+
res.sendFile(theme + urlPath, {root: path.resolve(__dirname, 'public/themes')}, function(err) {
491+
if (err) {
490492
next();
491493
}
492494
});

plugins/sdk/api/api.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ plugins.register("/permissions/features", function(ob) {
2727
common.returnOutput(params, config);
2828
})
2929
.catch(function(err) {
30-
common.returnMessage(params, 400, 'Error: ' + err);
30+
console.error("Error retrieving SDK config", err);
31+
common.returnMessage(params, 400, 'Error retrieving SDK config');
3132
})
3233
.finally(function() {
3334
resolve();
@@ -72,7 +73,8 @@ plugins.register("/permissions/features", function(ob) {
7273
common.returnOutput(params, res.config || {});
7374
})
7475
.catch(function(err) {
75-
common.returnMessage(params, 400, 'Error: ' + err);
76+
console.error("Error retrieving SDK config", err);
77+
common.returnMessage(params, 400, 'Error retrieving SDK config');
7678
});
7779
});
7880

plugins/two-factor-auth/frontend/public/templates/enter2fa_login.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@
8888
<%- inject_template.form %>
8989
<% } %>
9090
<div>
91-
<input type="hidden" value="<%- username %>" name="username"/>
92-
<input type="hidden" value="<%- password %>" name="password"/>
91+
<input type="hidden" value="<%= username %>" name="username"/>
92+
<input type="hidden" value="<%= password %>" name="password"/>
9393
<input type="hidden" value="<%= csrf %>" name="_csrf" />
9494
<input type="hidden" value="en" name="lang" id="form-lang" />
9595
<input id="login-button" value="Continue" type="submit" data-localize="two-factor-auth.continue"/>

plugins/two-factor-auth/frontend/public/templates/setup2fa.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@
8181
<% } %>
8282
<div>
8383
<input type="hidden" value="<%= secret_token %>" name="secret_token"/>
84-
<input type="hidden" value="<%- username %>" name="username"/>
85-
<input type="hidden" value="<%- password %>" name="password"/>
84+
<input type="hidden" value="<%= username %>" name="username"/>
85+
<input type="hidden" value="<%= password %>" name="password"/>
8686
<input type="hidden" value="<%= csrf %>" name="_csrf" />
8787
<input type="hidden" value="en" name="lang" id="form-lang" />
8888
</div>

0 commit comments

Comments
 (0)