Red Hat Bugzilla – Bug 982771
luci vs. sessions: check length of secret on startup
Last modified: 2014-10-14 00:12:35 EDT
1/ checking length of secret ---------------------------- luci should check if the beaker.session.secret value consists of 20+ chars as it is highly advisable for secret key used within SHA1-HMAC [1] (which is the case in the current deployment at the python-beaker level when handling sessions, specifically for integrity check during cookie-to-session mapping). By default, the pseudo-random secret is set when luci.ini file is being generated (upon first run of luci service) and this file is not expected to be user-serviceable (debugging, etc. putting aside now). The recipe to choose the secret (the whole config generation logic comes from python-paste-script) is made so as to select 25 characters, but does not guarantee it cannot be less (due to too many \n, \r, or = characters in the greater input pseudo-random vector). The intention of such a check would be to prevent both inexpert user modification and the case of "bad luck" with pseudorandom generator. 2/ stale sessions removal ------------------------- While sessions data are located in /var/run/luci/sessions and hence tmpfs or some kind of data cleaner might apply here, it's not the default nor common case. As python-beaker documentation explicitly states [2] (TurboGears2: [3]), it doesn't perform any sort of garbage collection on its own. Hence, we should consider taking this role and decrease the "entropy" at the mentioned location. There are more good reasons for doing so: - further lowering otherwise extremely unprobable session ID collision (NB: beside custom flash2 construct and maybe tg.i18n, nothing actively uses sessions, so not a big deal) - mitigating proactive sessions creation as described by TG2@SF#83 [4] and fixed in a newer TG2 release [5] + to check: cleanup on package removal. technical choices ----------------- Both (but independently) can be performed both in the initscript or adding hooks into call_on_startup/call_on_shutdown lists of LuciAppConfig in luci.config.app_cfg. At least for 2/, I think initscript is a better choice as most convenient is to call 'find' with appropriate -mtime argument anyway. [1] http://tools.ietf.org/html/rfc2104.html#section-3 [2] http://beaker.readthedocs.org/en/latest/sessions.html#removing-expired-old-sessions [3] https://turbogears.readthedocs.org/en/latest/turbogears/session.html [4] http://sourceforge.net/p/turbogears2/tickets/83/ [5] https://github.com/TurboGears/tg2/commit/b2656a11e4053e4465f01d0d9051f8e423fb1c15
re 2/ stale sessions removal: I've forgotten that this is already supported and default behavior on both start and stop action (if one wants to suppress it, it can be done in /etc/sysconfig/luci by uncommenting KEEP_RUNTIME_DATA=1 line.
Test results, after fresh installation: [first a sanity-check that we are not in conflict with standard no-touch use case] # service luci start > [...] > writing new private key to '/var/lib/luci/certs/host.pem' > Start luci... [ OK ] > Point your web browser to https://localhost.localdomain:8084 > (or equivalent) to access luci # wget -S --no-check-certificate https://localhost:8084 -O/dev/null \ |& grep HTTP > HTTP request sent, awaiting response... > HTTP/1.0 302 Found > HTTP request sent, awaiting response... > HTTP/1.0 302 Found > HTTP request sent, awaiting response... > HTTP/1.0 200 OK # grep beaker\\.session\\.secret /var/lib/luci/etc/luci.ini \ | cut -d= -f2 | tr -d ' \n' | wc -c > 25 [there is no conflict as the size of implicitly generated secret is 25 > 20] --- [now consider that one, against the advice, edits luci.ini = configuration predestined by authors of luci and changes beaker.session.secret value to something shorter than 20 characters, thus lowering the security of server-tracked user session data] # sed -i.orig \ 's|^[#]\?\(beaker\.session\.secret\s*=\).*|\1 1234567891234567891|' \ /var/lib/luci/etc/luci.ini # grep beaker\\.session\\.secret /var/lib/luci/etc/luci.ini \ | cut -d= -f2 | tr -d ' \n' | wc -c > 19 # service luci restart > Stop luci... [ OK ] > Start luci... [ OK ] > Point your web browser to https://localhost.localdomain:8084 > (or equivalent) to access luci # service luci status > No PID file /var/run/luci/luci.pid # tail -n2 /var/log/luci/luci.log > RuntimeError: Insufficient length of 'beaker.session.secret': 19 > Removing PID file /var/run/luci/luci.pid --- [to check for off-by-one error, use length of 20, i.e. smallest valid one] # sed -i \ 's|^[#]\?\(beaker\.session\.secret\s*=\).*|\1 12345678912345678912|' \ /var/lib/luci/etc/luci.ini # service luci restart > Stop luci... [FAILED] > Start luci... [ OK ] > Point your web browser to https://localhost.localdomain:8084 > (or equivalent) to access luci # service luci status > Server running in PID 29041 # tail -n2 /var/log/luci/luci.log > Starting server in PID 29041. > serving on 0.0.0.0:8084 view at https://127.0.0.1:8084 [i.e., works as expected]
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHSA-2014-1390.html