From e4d339627ec3291c90eaa12dbbed2f108d60d1b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Sch=C3=A4fer?= Date: Sat, 6 Feb 2021 11:13:43 +0100 Subject: [PATCH] Protect against incorrect domain name on the server side Instead of processing the input further and forwarding the credentials to prosody, we catch the error early on to prevent having to handle the 400 error code specially and to prevent the password from spilling in other components. Fixes #55. --- snikket_web/main.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/snikket_web/main.py b/snikket_web/main.py index 00d8f38..eef2d4a 100644 --- a/snikket_web/main.py +++ b/snikket_web/main.py @@ -52,6 +52,9 @@ async def index() -> quart.Response: return redirect(url_for("index")) +ERR_CREDENTIALS_INVALID = _l("Invalid username or password.") + + @bp.route("/login", methods=["GET", "POST"]) async def login() -> typing.Union[str, quart.Response]: if client.has_session and (await client.test_session()): @@ -63,16 +66,20 @@ async def login() -> typing.Union[str, quart.Response]: localpart, domain, resource = xmpputil.split_jid(jid) if not localpart: localpart, domain = domain, current_app.config["SNIKKET_DOMAIN"] - jid = "{}@{}".format(localpart, domain) - password = form.password.data - try: - await client.login(jid, password) - except quart.exceptions.Unauthorized: - form.password.errors.append( - _("Invalid username or password.") - ) + if domain != current_app.config["SNIKKET_DOMAIN"]: + # (a) prosody throws a 400 at us and I prefer to catch that here + # and (b) I don’t want to pass on this obviously not-for-here + # password further than necessary. + form.password.errors.append(ERR_CREDENTIALS_INVALID) else: - return redirect(url_for('user.index')) + jid = "{}@{}".format(localpart, domain) + password = form.password.data + try: + await client.login(jid, password) + except quart.exceptions.Unauthorized: + form.password.errors.append(ERR_CREDENTIALS_INVALID) + else: + return redirect(url_for('user.index')) return await render_template("login.html", form=form)