diff --git a/authserv/app_common.py b/authserv/app_common.py
index 9d5c8df10cec1b797839b68b94640a8942181049..32b6c0d4f1aa425be99e95de92ce63211f827ae1 100644
--- a/authserv/app_common.py
+++ b/authserv/app_common.py
@@ -1,3 +1,4 @@
+import re
 from flask import abort, current_app
 from authserv import auth
 from authserv import protocol
@@ -22,8 +23,34 @@ def check_ratelimit(request, username, source_ip):
             abort(503)
 
 
+def _validate_username(username):
+    """Validate a username before fetching it from the backend.
+
+    More of a syntax check than anything. It's just to save cycles in
+    case of (only the most trivial of) brute-force / exploitation
+    attempts.
+
+    Returns the validated username (type str).
+    """
+    if not username:
+        raise Exception('empty username')
+
+    if len(username) > 256:
+        raise Exception('name too long')
+
+    # This will throw a UnicodeEncodeError on non-ASCII usernames.
+    username = str(username)
+
+    # Check that it does not contain spaces or newlines.
+    if re.match(r'\s', username):
+        raise Exception('invalid characters in username')
+
+    return username
+
+
 def do_auth(username, service, shard, password, otp_token, source_ip,
             password_only=False):
+    # Username must be an ASCII string.
     bl = AuthBlackList(current_app.config.get('BLACKLIST_COUNT', 5),
                        current_app.config.get('BLACKLIST_PERIOD', 600),
                        current_app.config.get('BLACKLIST_TIME', 6*3600))
@@ -38,6 +65,12 @@ def do_auth(username, service, shard, password, otp_token, source_ip,
     retval = protocol.ERR_AUTHENTICATION_FAILURE
     errmsg = 'user does not exist'
     out_shard = None
+
+    try:
+        username = _validate_username(username)
+    except:
+        return (retval, errmsg, None)
+
     user = current_app.userdb.get_user(username, service, shard)
     if user:
         retval, errmsg = auth.authenticate(