diff --git a/server.py b/server.py index e8c8345..8d6af98 100755 --- a/server.py +++ b/server.py @@ -33,9 +33,17 @@ def index(): previousResponseCode = flask.request.args.get("code") return flask.render_template("index.html", code=previousResponseCode) +@app.route('/list-users') +def listUsers(): + users = db.session.query(FTPUser) + previousResponseCode = flask.request.args.get("code") + return flask.render_template("list_users.html", users=users, code=previousResponseCode) + @app.route('/create-user', methods=["POST"]) def createUser(): - createUser(flask.request.form) + error = createUser(flask.request.form) + if error: + return (error, HTTP_INTERNAL_ERR) return (EMPTY, HTTP_EMPTY) @app.route('/delete-user', methods=["POST"]) @@ -46,28 +54,41 @@ def deleteUser(): return ("User doesn't exist.", 405) db.session.delete(user) db.session.commit() - subprocess.run(["/usr/bin/sudo", "./scripts/delete_user.sh", userToDelete]) + + # be extra safe and use value from database + subprocess.run(["/usr/bin/sudo", "./scripts/delete_user.sh", user.username]) return ("/list-users", 200) -@app.route('/list-users') -def listUsers(): - users = db.session.query(FTPUser) - previousResponseCode = flask.request.args.get("code") - return flask.render_template("list_users.html", users=users, code=previousResponseCode) +def sanityCheckInputString(string, stringName): + + # sanity check input, let's not built RCE # + try: + string = string.encode("ascii").decode("ascii") + except UnicodeEncodeError: + return "Error: {} contains non-ascii characters".format(stringName) + + if not string.isalpha(): + return "Error: {} contains non-alpha characters".format(stringName) + + return None def createUser(webform): # command line useradd requires a pre-encrypted password cryptPass = crypt.crypt(webform['password'], PAM_PASSWD_SALT) - subprocess.run(["/usr/bin/sudo", "./scripts/create_user.sh", cryptPass, webform['username']]) + + username = webform['username'] + error = sanityCheckInputString(username, "username") + if error: + return error + + subprocess.run(["/usr/bin/sudo", "./scripts/create_user.sh", cryptPass, username]) # track added users to prevent deletion of other users and listing # db.session.add(FTPUser(username=webform['username'])) db.session.commit() -def executeScript(scriptName): - path = os.path.expanduser(scriptName) - subprocess.Popen(path) + return None class FTPUser(db.Model):