Module: check_mk
Branch: master
Commit: 54ed4838cfcc62164eeb746e2e17b08a2457cd03
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=54ed4838cfcc62…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Mon Sep 17 11:58:05 2018 +0200
6618 SEC Fixed missing CSRF protection for host diagnostic AJAX calls
The AJAX calls used by the host diagnostic page were not correctly using
CSRF tokens to protect logged in users against malicious links that could
trigger actions.
CMK-963
Change-Id: I0999dc8eed89065064c41de865c00759ca40470b
---
.werks/6618 | 12 ++++++++++++
cmk/gui/htmllib.py | 4 ++--
cmk/gui/wato/__init__.py | 15 ++++++++++++---
web/htdocs/js/wato.js | 20 +++++++++++---------
4 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/.werks/6618 b/.werks/6618
new file mode 100644
index 0000000..9218c52
--- /dev/null
+++ b/.werks/6618
@@ -0,0 +1,12 @@
+Title: Fixed missing CSRF protection for host diagnostic AJAX calls
+Level: 1
+Component: wato
+Compatible: compat
+Edition: cre
+Version: 1.6.0i1
+Date: 1537178166
+Class: security
+
+The AJAX calls used by the host diagnostic page were not correctly using
+CSRF tokens to protect logged in users against malicious links that could
+trigger actions.
diff --git a/cmk/gui/htmllib.py b/cmk/gui/htmllib.py
index 303fa8f..998e5ee 100644
--- a/cmk/gui/htmllib.py
+++ b/cmk/gui/htmllib.py
@@ -909,11 +909,11 @@ class TransactionManager(object):
def get(self):
"""Returns a transaction ID that can be used during a subsequent
action"""
if not self._current_transid:
- self._current_transid = self._fresh_transid()
+ self._current_transid = self.fresh_transid()
return self._current_transid
- def _fresh_transid(self):
+ def fresh_transid(self):
"""Compute a (hopefully) unique transaction id.
This is generated during rendering of a form or an action link, stored
diff --git a/cmk/gui/wato/__init__.py b/cmk/gui/wato/__init__.py
index 97a05ad..0f2e2c2 100644
--- a/cmk/gui/wato/__init__.py
+++ b/cmk/gui/wato/__init__.py
@@ -3041,7 +3041,7 @@ class ModeDiagHost(WatoMode):
html.open_td(class_="icons")
html.open_div()
html.img("images/icon_reload.png", class_="icon",
id="%s_img" % ident)
- html.open_a(href="javascript:start_host_diag_test(\'%s\',
\'%s\');" % (ident, self._hostname))
+ html.open_a(href="")
html.img("images/icon_reload.png", class_=["icon",
"retry"], id_="%s_retry" % ident, title=_('Retry this test'))
html.close_a()
html.close_div()
@@ -3053,7 +3053,8 @@ class ModeDiagHost(WatoMode):
html.close_tr()
html.close_table()
- html.javascript('start_host_diag_test("%s",
"%s")' % (ident, self._hostname))
+ html.javascript('start_host_diag_test(%s, %s, %s)' %
+ (json.dumps(ident), json.dumps(self._hostname),
json.dumps(html.transaction_manager.fresh_transid())))
html.close_td()
html.close_tr()
@@ -3155,6 +3156,9 @@ class ModeAjaxDiagHost(WatoWebApiMode):
if not config.user.may('wato.diag_host'):
raise MKAuthException(_('You are not permitted to perform this
action.'))
+ if not html.check_transaction():
+ raise MKAuthException(_("Invalid transaction"))
+
request = self.webapi_request()
hostname = request.get("host")
@@ -3212,7 +3216,12 @@ class ModeAjaxDiagHost(WatoWebApiMode):
else:
args[9] = request.get("snmpv3_security_name")
- return watolib.check_mk_automation(host.site_id(), "diag-host",
[hostname, _test] + args)
+ result = watolib.check_mk_automation(host.site_id(), "diag-host",
[hostname, _test] + args)
+ return {
+ "next_transid" : html.transaction_manager.fresh_transid(),
+ "status_code" : result[0],
+ "output" : result[1],
+ }
#.
diff --git a/web/htdocs/js/wato.js b/web/htdocs/js/wato.js
index 29d7283..0ae4409 100644
--- a/web/htdocs/js/wato.js
+++ b/web/htdocs/js/wato.js
@@ -1027,12 +1027,12 @@ function wato_toggle_folder(event, oDiv, on) {
// | |___/ |
// +----------------------------------------------------------------------+
-function handle_host_diag_result(ident, response_json) {
+function handle_host_diag_result(data, response_json) {
var response = JSON.parse(response_json);
- var img = document.getElementById(ident + '_img');
- var log = document.getElementById(ident + '_log');
- var retry = document.getElementById(ident + '_retry');
+ var img = document.getElementById(data.ident + '_img');
+ var log = document.getElementById(data.ident + '_log');
+ var retry = document.getElementById(data.ident + '_retry');
remove_class(img, "reloading");
var text = "";
@@ -1042,23 +1042,24 @@ function handle_host_diag_result(ident, response_json) {
text = "API Error:" + response.result;
} else {
- if (response.result[0] == 1) {
+ if (response.result.status_code == 1) {
img.src = "images/icon_failed.png";
log.className = "log diag_failed";
} else {
img.src = "images/icon_success.png";
log.className = "log diag_success";
}
- text = response.result[1];
+ text = response.result.output;
}
log.innerText = text;
retry.src = "images/icon_reload.png";
retry.style.display = 'inline';
+ retry.parentNode.href =
"javascript:start_host_diag_test('"+data.ident+"',
'"+data.hostname+"',
'"+response.result.next_transid+"');";
}
-function start_host_diag_test(ident, hostname) {
+function start_host_diag_test(ident, hostname, transid) {
var log = document.getElementById(ident + '_log');
var img = document.getElementById(ident + '_img');
var retry = document.getElementById(ident + '_retry');
@@ -1066,7 +1067,8 @@ function start_host_diag_test(ident, hostname) {
retry.style.display = 'none';
var vars = '';
- vars = '&ipaddress=' +
encodeURIComponent(document.getElementsByName('vs_host_p_ipaddress')[0].value);
+ vars = '&_transid=' + encodeURIComponent(transid);
+ vars += '&ipaddress=' +
encodeURIComponent(document.getElementsByName('vs_host_p_ipaddress')[0].value);
if (document.getElementsByName("vs_host_p_snmp_community_USE")[0].checked)
@@ -1106,7 +1108,7 @@ function start_host_diag_test(ident, hostname) {
log.innerHTML = "...";
get_url("wato_ajax_diag_host.py?host=" + encodeURIComponent(hostname)
+ "&_test=" + encodeURIComponent(ident) + vars,
- handle_host_diag_result, ident);
+ handle_host_diag_result, { "hostname": hostname,
"ident": ident });
}
// .-Active Checks---------------------------------------------------------.