diff options
author | Paul "LeoNerd" Evans <paul@matrix.org> | 2014-09-23 15:58:44 +0100 |
---|---|---|
committer | Paul "LeoNerd" Evans <paul@matrix.org> | 2014-09-23 15:58:44 +0100 |
commit | c03176af59adfe0d60ffd8beb8bf262b4563d20b (patch) | |
tree | 4da3a30d07d9acffbf863e859550703ba9a47c34 /synapse/rest/register.py | |
parent | Config values are almost never 'None', but they might be empty string. Detect... (diff) | |
download | synapse-c03176af59adfe0d60ffd8beb8bf262b4563d20b.tar.xz |
Send an HMAC(SHA1) protecting the User ID for the ReCAPTCHA bypass, rather than simply the secret itself, so it's useless if that HMAC leaks
Diffstat (limited to 'synapse/rest/register.py')
-rw-r--r-- | synapse/rest/register.py | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/synapse/rest/register.py b/synapse/rest/register.py index 66cef26ada..14d1ab018e 100644 --- a/synapse/rest/register.py +++ b/synapse/rest/register.py @@ -21,6 +21,8 @@ from synapse.api.constants import LoginType from base import RestServlet, client_path_pattern import synapse.util.stringutils as stringutils +from hashlib import sha1 +import hmac import json import logging import urllib @@ -142,7 +144,7 @@ class RegisterRestServlet(RestServlet): if not self.hs.config.enable_registration_captcha: raise SynapseError(400, "Captcha not required.") - yield self._check_recaptcha(request, register_json) + yield self._check_recaptcha(request, register_json, session) session[LoginType.RECAPTCHA] = True # mark captcha as done self._save_session(session) @@ -151,14 +153,27 @@ class RegisterRestServlet(RestServlet): }) @defer.inlineCallbacks - def _check_recaptcha(self, request, register_json): - if "captcha_bypass_secret" in register_json: - if (self.hs.config.captcha_bypass_secret and - register_json["captcha_bypass_secret"] == - self.hs.config.captcha_bypass_secret): + def _check_recaptcha(self, request, register_json, session): + if ("captcha_bypass_hmac" in register_json and + self.hs.config.captcha_bypass_secret): + if "user" not in register_json: + raise SynapseError(400, "Captcha bypass needs 'user'") + + want = hmac.new( + key=self.hs.config.captcha_bypass_secret, + msg=register_json["user"], + digestmod=sha1, + ).hexdigest() + + # str() because otherwise hmac complains that 'unicode' does not + # have the buffer interface + got = str(register_json["captcha_bypass_hmac"]) + + if hmac.compare_digest(want, got): + session["user"] = register_json["user"] defer.returnValue(None) else: - raise SynapseError(400, "Captcha bypass secret incorrect", + raise SynapseError(400, "Captcha bypass HMAC incorrect", errcode=Codes.CAPTCHA_NEEDED) challenge = None @@ -209,6 +224,10 @@ class RegisterRestServlet(RestServlet): # captcha should've been done by this stage! raise SynapseError(400, "Captcha is required.") + if ("user" in session and "user" in register_json and + session["user"] != register_json["user"]): + raise SynapseError(400, "Cannot change user ID during registration") + password = register_json["password"].encode("utf-8") desired_user_id = (register_json["user"].encode("utf-8") if "user" in register_json else None) |