Module: check_mk
Branch: master
Commit: 5416397199adf777de261cdaa8880138b83e1706
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=5416397199adf7…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Wed Nov 12 14:15:08 2014 +0100
SEC: Replaced insecure auth.secret mechanism
---
.werks/1069 | 25 +++++++++++++++++++++++++
ChangeLog | 2 ++
web/htdocs/lib.py | 14 ++++++++++++++
web/htdocs/login.py | 12 ++++++++----
web/htdocs/wato.py | 12 +-----------
5 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/.werks/1069 b/.werks/1069
new file mode 100644
index 0000000..86467f7
--- /dev/null
+++ b/.werks/1069
@@ -0,0 +1,25 @@
+Title: Replaced insecure auth.secret mechanism
+Level: 2
+Component: multisite
+Compatible: incomp
+Version: 1.2.5i7
+Date: 1415797737
+Class: security
+
+We replaced a insecure mechanism of generating the auth.secret which
+is used during construction of the authentication cookies when a user
+logs into the Check_MK Web GUI to make the authentication cookie only
+valid for an individual site or a group of sites connected in a
+distributed setup.
+
+What you have to know about:
+
+When the first user accesses the Web GUI after the update to this version,
+all currently valid auth cookies of all users will be invalidated. As a
+result all users will need to login again.
+
+In distributed setups you will also need to do a replication from the
+master site (which generated a new secret) to all slave sites (which
+generated another secret themselfs). The replication will synchronize
+the new secret of the master to all slaves which should make the
+transparent authentication between all sites work again.
diff --git a/ChangeLog b/ChangeLog
index 9cf93bd..9cf34d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,8 @@
* 1493 Added config option "Default filter group" to set the initial
network topology view filter...
* 1497 Implemented password policy capabilities for local users...
* 1499 SEC: Fixed XSS injections in different places...
+ * 1069 SEC: Replaced insecure auth.secret mechanism...
+ NOTE: Please refer to the migration notes!
* 1164 FIX: Fixed links from servicegroup overviews to single servicegroups
* 1166 FIX: Also prevting stylesheet update issues during version updates (just like
for JS files)
* 1481 FIX: Fix broken layout of Host-, Service- and Contactgroup filters
diff --git a/web/htdocs/lib.py b/web/htdocs/lib.py
index 3477ca1..64bde40 100644
--- a/web/htdocs/lib.py
+++ b/web/htdocs/lib.py
@@ -133,6 +133,20 @@ except:
a.sort()
return a
+# We should use /dev/random here for cryptographic safety. But
+# that involves the great problem that the system might hang
+# because of loss of entropy. So we hope /dev/urandom is enough.
+# Furthermore we filter out non-printable characters. The byte
+# 0x00 for example does not make it through HTTP and the URL.
+def get_random_string(size):
+ secret = ""
+ urandom = file("/dev/urandom")
+ while len(secret) < size:
+ c = urandom.read(1)
+ if ord(c) >= 48 and ord(c) <= 90:
+ secret += c
+ return secret
+
# Generates a unique id
def gen_id():
try:
diff --git a/web/htdocs/login.py b/web/htdocs/login.py
index e7007e8..13a81bf 100644
--- a/web/htdocs/login.py
+++ b/web/htdocs/login.py
@@ -50,7 +50,6 @@ def site_cookie_name(site_id = None):
# Reads the auth secret from a file. Creates the files if it does
# not exist. Having access to the secret means that one can issue valid
# cookies for the cookie auth.
-# FIXME: Secret auch replizieren
def load_secret():
secret_path = '%s/auth.secret' % os.path.dirname(defaults.htpasswd_file)
secret = ''
@@ -58,9 +57,14 @@ def load_secret():
secret = file(secret_path).read().strip()
# Create new secret when this installation has no secret
- if secret == '':
- secret = md5(str(time.time())).hexdigest()
- file(secret_path, 'w').write(secret + "\n")
+ #
+ # In past versions we used another bad approach to generate a secret. This
+ # checks for such secrets and creates a new one. This will invalidate all
+ # current auth cookies which means that all logged in users will need to
+ # renew their login after update.
+ if secret == '' or len(secret) == 32:
+ secret = get_random_string(256)
+ file(secret_path, 'w').write(secret)
return secret
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 08fcac2..aef5840 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -11029,17 +11029,7 @@ def get_login_secret(create_on_demand = False):
except:
if not create_on_demand:
return None
- # We should use /dev/random here for cryptographic safety. But
- # that involves the great problem that the system might hang
- # because of loss of entropy. So we hope /dev/urandom is enough.
- # Furthermore we filter out non-printable characters. The byte
- # 0x00 for example does not make it through HTTP and the URL.
- secret = ""
- urandom = file("/dev/urandom")
- while len(secret) < 32:
- c = urandom.read(1)
- if ord(c) >= 48 and ord(c) <= 90:
- secret += c
+ secret = get_random_string(32)
write_settings_file(path, secret)
return secret