diff --git a/engine/apps/alerts/paging.py b/engine/apps/alerts/paging.py index b03f52d7..5121d017 100644 --- a/engine/apps/alerts/paging.py +++ b/engine/apps/alerts/paging.py @@ -16,6 +16,7 @@ from apps.alerts.tasks.notify_user import notify_user_task from apps.schedules.ical_utils import get_cached_oncall_users_for_multiple_schedules from apps.schedules.models import OnCallSchedule from apps.user_management.models import Organization, Team, User +from common.utils import escape_html UserNotifications = list[tuple[User, bool]] @@ -145,6 +146,10 @@ def direct_paging( if alert_group and alert_group.resolved: raise DirectPagingAlertGroupResolvedError + # https://github.com/grafana/oncall-private/issues/2760 + title = escape_html(title) + message = escape_html(message) + if title is None: title = _construct_title(from_user, team, users) diff --git a/engine/apps/alerts/tests/test_paging.py b/engine/apps/alerts/tests/test_paging.py index 0528782d..d6bad7a2 100644 --- a/engine/apps/alerts/tests/test_paging.py +++ b/engine/apps/alerts/tests/test_paging.py @@ -312,3 +312,25 @@ def test_construct_title(make_organization, make_team, make_user_for_organizatio assert _construct_title(from_user, team, multiple_users) == _title( f"{team.name}, {user1.username}, {user2.username} and {user3.username}" ) + + +@pytest.mark.django_db +def test_direct_paging_title_and_message_are_html_escaped(make_organization, make_user_for_organization): + dirty_input = "" + clean_input = "<script>alert('hacked');</script>" + + organization = make_organization() + from_user = make_user_for_organization(organization) + other_user = make_user_for_organization(organization) + + direct_paging(organization, from_user, dirty_input, dirty_input, users=[(other_user, False)]) + + # alert group created + alert_groups = AlertGroup.objects.all() + assert alert_groups.count() == 1 + ag = alert_groups.get() + alert = ag.alerts.get() + + assert ag.web_title_cache == clean_input + assert alert.title == clean_input + assert alert.message == clean_input diff --git a/engine/common/utils.py b/engine/common/utils.py index 395a1306..dc20b9ec 100644 --- a/engine/common/utils.py +++ b/engine/common/utils.py @@ -249,7 +249,7 @@ def clean_markup(text): def escape_html(text): - return html.escape(text, quote=False) + return html.escape(text, quote=False) if text else text def urlize_with_respect_to_a(html):