mirror of
https://github.com/GSA/notifications-api.git
synced 2026-04-03 09:00:13 -04:00
Escape special characters in search by recipient
SQLAlchemy handles escaping anything that could allow a SQL injection
attack. But it doesn’t escape the characters used for wildcard
searching. This is the reason we’re able to do `.like('%example%')`
at all.
But we shouldn’t be letting our users search with wildcard characters,
so we need to escape them. Which is what this commit does.
This commit is contained in:
@@ -455,6 +455,12 @@ def dao_get_notifications_by_to_field(service_id, search_term, notification_type
|
||||
else:
|
||||
raise InvalidRequest("Only email and SMS can use search by recipient", 400)
|
||||
|
||||
for special_character in {'_', '%', '/'}:
|
||||
normalised = normalised.replace(
|
||||
special_character,
|
||||
'\\{}'.format(special_character)
|
||||
)
|
||||
|
||||
filters = [
|
||||
Notification.service_id == service_id,
|
||||
Notification.normalised_to.like("%{}%".format(normalised)),
|
||||
|
||||
@@ -1769,6 +1769,45 @@ def test_dao_get_notifications_by_to_field_matches_partial_emails(sample_email_t
|
||||
assert notification_2.id not in notification_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize('search_term, expected_result_count', [
|
||||
('foobar', 1),
|
||||
('foo', 2),
|
||||
('bar', 2),
|
||||
('foo%', 1),
|
||||
('%%bar', 1),
|
||||
('%_', 1),
|
||||
('%', 2),
|
||||
('_', 1),
|
||||
('/', 1),
|
||||
('%foo', 0),
|
||||
('%_%', 0),
|
||||
('example.com', 4),
|
||||
])
|
||||
def test_dao_get_notifications_by_to_field_escapes(
|
||||
sample_email_template,
|
||||
search_term,
|
||||
expected_result_count,
|
||||
):
|
||||
|
||||
for email_address in {
|
||||
'foo%_@example.com',
|
||||
'%%bar@example.com',
|
||||
'foobar@example.com',
|
||||
'/@example.com',
|
||||
}:
|
||||
create_notification(
|
||||
template=sample_email_template,
|
||||
to_field=email_address,
|
||||
normalised_to=email_address,
|
||||
)
|
||||
|
||||
assert len(dao_get_notifications_by_to_field(
|
||||
sample_email_template.service_id,
|
||||
search_term,
|
||||
notification_type='email',
|
||||
)) == expected_result_count
|
||||
|
||||
|
||||
@pytest.mark.parametrize('search_term', [
|
||||
'001',
|
||||
'100',
|
||||
|
||||
Reference in New Issue
Block a user