diff --git a/snowflake/update_snowflake_user.py b/snowflake/update_snowflake_user.py index f8dcbbe..15c9524 100644 --- a/snowflake/update_snowflake_user.py +++ b/snowflake/update_snowflake_user.py @@ -12,6 +12,7 @@ For example: sudo ln -s "/usr/local/bin/my python3.7" /usr/local/bin/pam_rotation_venv_python3 ''' import json +import re import sys import base64 @@ -32,6 +33,18 @@ print("# Error: The 'snowflake connector' package could not be imported. Run 'pip install snowflake-connector-python' to install it.") exit(1) + +def _escape_identifier(name: str) -> str: + + # Unquoted identifier names are matched case-insensitively by Snowflake; leave those alone. + # Anything else gets double-quoted, with embedded double quotes doubled, so the name cannot + # break out of the identifier and inject SQL. + if re.fullmatch(r"[A-Za-z_][A-Za-z0-9_$]*", name): + return name + escaped = name.replace('"', '""') + return f'"{escaped}"' + + def rotate(snowflake_account_name, snowflake_admin_user, snowflake_admin_pass, snowflake_user_name, new_password): """ Connects with Snowflake using the snowflake.connector module. @@ -61,11 +74,11 @@ def rotate(snowflake_account_name, snowflake_admin_user, snowflake_admin_pass, s # Create a cursor object cur = conn.cursor() - + # Change new user's password try: - change_pass_query = f"ALTER USER {snowflake_user_name} SET PASSWORD = '{new_password}'" - cur.execute(change_pass_query) + change_pass_query = f"ALTER USER {_escape_identifier(snowflake_user_name)} SET PASSWORD = %s" + cur.execute(change_pass_query, (new_password,)) except Exception as E: print(f"Unable to update the password. Error: {E}") exit(1)