notify-api-91 sanitize SQL inputs against injection

This commit is contained in:
Kenneth Kehl
2023-07-14 09:07:23 -07:00
parent 4417838b09
commit e6077c187c
7 changed files with 61 additions and 60 deletions

View File

@@ -19,21 +19,19 @@ INBOUND_NUMBER = current_app.config['NOTIFY_INTERNATIONAL_SMS_SENDER'].strip('+'
def upgrade():
op.execute("INSERT INTO service_sms_senders (id, sms_sender, service_id, is_default, created_at) "
"VALUES ('{}', '{}', '{}',false, now())".format(
SMS_SENDER_ID,
INBOUND_NUMBER,
NOTIFY_SERVICE_ID
))
sql = f"""INSERT INTO service_sms_senders (id, sms_sender, service_id, is_default, created_at)
VALUES ('{SMS_SENDER_ID}', '{INBOUND_NUMBER}', '{NOTIFY_SERVICE_ID}',false, now())"""
op.execute(sql)
inbound_number_id = uuid.uuid4()
# by adding a row in inbound_number we ensure the number isn't added to the table and assigned to a service.
inbound_number_sql = f"""INSERT INTO INBOUND_NUMBERS (id, number, provider, active, created_at)
VALUES('{inbound_number_id}', '{INBOUND_NUMBER}', 'mmg', false, now())
"""
op.execute(inbound_number_sql)
op.execute("INSERT INTO INBOUND_NUMBERS (id, number, provider, active, created_at) VALUES('{}', "
"'{}', '{}', false, now())".format(inbound_number_id, INBOUND_NUMBER, 'mmg'))
def downgrade():
delete_sms_sender = f"delete from service_sms_senders where id = '{SMS_SENDER_ID}'"
delete_inbound_number = f"delete from inbound_numbers where number = '{INBOUND_NUMBER}'"
op.execute(delete_sms_sender)
op.execute(delete_inbound_number)
op.execute("delete from service_sms_senders where id = '{}'".format(SMS_SENDER_ID))
op.execute("delete from inbound_numbers where number = '{}'".format(INBOUND_NUMBER))

View File

@@ -34,13 +34,17 @@ def upgrade():
services = conn.execute(find_services_sql)
for service in services:
setting = conn.execute(f"SELECT service_id, channel, provider FROM service_broadcast_settings WHERE service_id = '{service.id}';").first()
input_params = {"service_id": service.id}
setting = conn.execute(
"SELECT service_id, channel, provider FROM service_broadcast_settings WHERE service_id=:service_id;",
input_params).first()
if setting:
print(f"Service {service.id} already has service_broadcast_settings. No action required")
else:
channel = "severe" if service.restricted else "test"
print(f"Service {service.id} does not have service_broadcast_settings. Will insert one with channel {channel}")
conn.execute(f"INSERT INTO service_broadcast_settings (service_id, channel, created_at) VALUES ('{service.id}', '{channel}', now());")
conn.execute("INSERT INTO service_broadcast_settings (service_id, channel, created_at) VALUES (%s, %s, now());",
{service.id, channel})
def downgrade():

View File

@@ -19,7 +19,7 @@ def upgrade():
sa.Column('name', sa.String(length=255), nullable=False),
sa.PrimaryKeyConstraint('name'))
for provider in PROVIDER_TYPES:
op.execute(f"INSERT INTO broadcast_provider_types VALUES ('{provider}')")
op.execute("INSERT INTO broadcast_provider_types VALUES ('{}')".format(provider))
op.create_foreign_key('service_broadcast_settings_provider_fkey',
'service_broadcast_settings',
'broadcast_provider_types',

View File

@@ -34,16 +34,16 @@ def upgrade():
op.execute(f"update {table_name} set {col}='{val}' where {select_by_col} = '{select_by_val}'")
# modify content of verification email in templates
table_name = 'templates'
col = 'content'
# table_name = 'templates'
# col = 'content'
val = """Hi ((name)),\n\nTo complete your registration for US Notify please click the link below\n\n((url))"""
select_by_col = 'name'
select_by_val = 'Notify email verification code'
op.execute(f"update {table_name} set {col}='{val}' where {select_by_col} = '{select_by_val}'")
# select_by_col = 'name'
# select_by_val = 'Notify email verification code'
op.execute("update templates set content='{}' where name = 'Notify email verification code'".format(val))
# modify content of verification email in templates_history
table_name = 'templates_history'
op.execute(f"update {table_name} set {col}='{val}' where {select_by_col} = '{select_by_val}'")
# table_name = 'templates_history'
op.execute("update templates_history set content='{}' where name = 'Notify email verification code'".format(val))
# TODO: modify other templates as necessary and re-run this migration

View File

@@ -14,19 +14,20 @@ from flask import current_app
service_id = current_app.config['NOTIFY_SERVICE_ID']
def upgrade():
op.get_bind()
# modify name of default service user in services
table_name = 'services'
col = 'name'
val = 'US Notify'
select_by_col = 'id'
select_by_val = service_id
op.execute(f"update {table_name} set {col}='{val}' where {select_by_col} = '{select_by_val}'")
# table_name = 'services'
# col = 'name'
# val = 'US Notify'
# select_by_col = 'id'
# select_by_val = service_id
op.execute("update services set name='US Notify' where id = '{}'".format(service_id))
table_name = 'services_history'
op.execute(f"update {table_name} set {col}='{val}' where {select_by_col} = '{select_by_val}'")
# table_name = 'services_history'
op.execute("update services_history set name='US Notify' where id = '{}'".format(service_id))
def downgrade():

View File

@@ -18,43 +18,38 @@ INBOUND_NUMBER_ID = '9b5bc009-b847-4b1f-8a54-f3b5f95cff18'
INBOUND_NUMBER = current_app.config['NOTIFY_INTERNATIONAL_SMS_SENDER'].strip('+')
DEFAULT_SERVICE_ID = current_app.config['NOTIFY_SERVICE_ID']
def upgrade():
op.get_bind()
# delete the previous inbound_number with mmg as provider
table_name = 'inbound_numbers'
select_by_col = 'number'
select_by_val = INBOUND_NUMBER
op.execute(f"delete from {table_name} where {select_by_col} = '{select_by_val}'")
# table_name = 'inbound_numbers'
# select_by_col = 'number'
# select_by_val = INBOUND_NUMBER
op.execute("delete from inbound_numbers where number = '{}'".format(INBOUND_NUMBER))
# add the inbound number for the default service to inbound_numbers
table_name = 'inbound_numbers'
provider = 'sns'
active = 'true'
op.execute(f"insert into {table_name} (id, number, provider, service_id, active, created_at) VALUES('{INBOUND_NUMBER_ID}', '{INBOUND_NUMBER}', '{provider}','{DEFAULT_SERVICE_ID}', '{active}', 'now()')")
op.execute("insert into inbound_numbers "
"(id, number, provider, service_id, active, created_at) "
"VALUES ('{}', '{}', 'sns', '{}', 'true', now())".format(INBOUND_NUMBER_ID,
INBOUND_NUMBER, DEFAULT_SERVICE_ID))
# add the inbound number for the default service to service_sms_senders
table_name = 'service_sms_senders'
sms_sender = INBOUND_NUMBER
select_by_col = 'id'
select_by_val = '286d6176-adbe-7ea7-ba26-b7606ee5e2a4'
op.execute(f"update {table_name} set {'sms_sender'}='{sms_sender}' where {select_by_col} = '{select_by_val}'")
op.execute("update service_sms_senders set sms_sender='{}' "
"where id = '286d6176-adbe-7ea7-ba26-b7606ee5e2a4'".format(INBOUND_NUMBER))
# add the inbound number for the default service to inbound_numbers
table_name = 'service_permissions'
permission = 'inbound_sms'
active = 'true'
op.execute(f"insert into {table_name} (service_id, permission, created_at) VALUES('{DEFAULT_SERVICE_ID}', '{permission}', 'now()')")
op.execute("insert into service_permissions (service_id, permission, created_at) "
"VALUES('{}', 'inbound_sms', now())".format(DEFAULT_SERVICE_ID))
# pass
def downgrade():
delete_sms_sender = f"delete from service_sms_senders where inbound_number_id = '{INBOUND_NUMBER_ID}'"
delete_inbound_number = f"delete from inbound_numbers where number = '{INBOUND_NUMBER}'"
delete_service_inbound_permission = f"delete from service_permissions where service_id = '{DEFAULT_SERVICE_ID}' and permission = 'inbound_sms'"
recreate_mmg_inbound_number = f"insert into inbound_numbers (id, number, provider, service_id, active, created_at) VALUES('d7aea27f-340b-4428-9b20-4470dd978bda', '{INBOUND_NUMBER}', 'mmg', 'null', 'false', 'now()')"
op.execute(delete_sms_sender)
op.execute(delete_inbound_number)
op.execute(delete_service_inbound_permission)
op.execute(recreate_mmg_inbound_number)
op.execute("delete from service_sms_senders where inbound_number_id = '{}'".format(INBOUND_NUMBER_ID))
op.execute("delete from inbound_numbers where number = '{}'".format(INBOUND_NUMBER))
op.execute("delete from service_permissions where service_id = '{}' and permission = 'inbound_sms'".format(
DEFAULT_SERVICE_ID))
op.execute("insert into inbound_numbers (id, number, provider, service_id, active, created_at) "
"VALUES('d7aea27f-340b-4428-9b20-4470dd978bda', '{}', 'mmg', 'null', 'false', 'now()')".format(
INBOUND_NUMBER))
# pass

View File

@@ -19,13 +19,16 @@ NEW_SMS_NUMBER = current_app.config['NOTIFY_INTERNATIONAL_SMS_SENDER'].strip('+'
def upgrade():
op.alter_column("service_sms_senders", "sms_sender", type_=sa.types.String(length=255))
op.alter_column("inbound_numbers", "number", type_=sa.types.String(length=255))
op.execute(f"UPDATE service_sms_senders SET sms_sender = '+{NEW_SMS_NUMBER}' WHERE sms_sender IN ('{OLD_SMS_NUMBER}', '{NEW_SMS_NUMBER}')")
op.execute(f"UPDATE inbound_numbers SET number = '+{NEW_SMS_NUMBER}' WHERE number IN ('{OLD_SMS_NUMBER}', '{NEW_SMS_NUMBER}')")
op.execute("UPDATE service_sms_senders SET sms_sender = '+{}' "
"WHERE sms_sender IN ('{}', '{}')".format(NEW_SMS_NUMBER, OLD_SMS_NUMBER, NEW_SMS_NUMBER))
op.execute("UPDATE inbound_numbers SET number = '+{}' "
"WHERE number IN ('{}', '{}')".format(NEW_SMS_NUMBER, OLD_SMS_NUMBER, NEW_SMS_NUMBER))
def downgrade():
op.execute(f"UPDATE service_sms_senders SET sms_sender = '{OLD_SMS_NUMBER}' WHERE sms_sender = '+{NEW_SMS_NUMBER}'")
op.execute(f"UPDATE inbound_numbers SET number = '{OLD_SMS_NUMBER}' WHERE number = '+{NEW_SMS_NUMBER}'")
op.execute("UPDATE service_sms_senders SET sms_sender = '{}' "
"WHERE sms_sender = '+{}'".format(OLD_SMS_NUMBER, NEW_SMS_NUMBER))
op.execute("UPDATE inbound_numbers SET number = '{}' "
"WHERE number = '+{}'".format(OLD_SMS_NUMBER, NEW_SMS_NUMBER))
op.alter_column("service_sms_senders", "sms_sender", type_=sa.types.String(length=11))
op.alter_column("inbound_numbers", "number", type_=sa.types.String(length=11))