From 32b9e9a750122d4384587c7198999c16792a9d48 Mon Sep 17 00:00:00 2001 From: Seth Michael Larson Date: Wed, 29 Jul 2026 10:47:00 -0500 Subject: [PATCH] Sanitize imported iCalendar/ICS HTML --- apps/events/importer.py | 2 ++ apps/events/tests/test_importer.py | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/apps/events/importer.py b/apps/events/importer.py index ec8603f93..6dfdb33b0 100644 --- a/apps/events/importer.py +++ b/apps/events/importer.py @@ -8,6 +8,7 @@ from apps.events.models import Event, EventLocation, OccurringRule from apps.events.utils import extract_date_or_datetime +from pydotorg.markup import sanitize logger = logging.getLogger(__name__) @@ -46,6 +47,7 @@ def import_event(self, event_data): uid = event_data["UID"] title = event_data["SUMMARY"] description = event_data.get("DESCRIPTION", "") + description = sanitize(description) location, _ = EventLocation.objects.get_or_create(calendar=self.calendar, name=event_data["LOCATION"]) defaults = { "title": title, diff --git a/apps/events/tests/test_importer.py b/apps/events/tests/test_importer.py index c4d787923..ebb55f31f 100644 --- a/apps/events/tests/test_importer.py +++ b/apps/events/tests/test_importer.py @@ -1,6 +1,7 @@ from pathlib import Path from django.test import TestCase +from django.urls import reverse from django.utils.timezone import datetime, make_aware from apps.events.importer import ICSImporter @@ -150,3 +151,27 @@ def test_import_event_does_not_exclude_ending_day_when_all_day_is_false(self): make_aware(datetime(year=2013, month=8, day=2, hour=20, minute=30)), single_day_event.next_or_previous_time.dt_end, ) + + def test_import_event_escaped(self): + ical = """BEGIN:VCALENDAR +BEGIN:VEVENT +DTSTART;VALUE=DATE:20150328 +DTEND;VALUE=DATE:20150330 +DTSTAMP:20150202T092425Z +UID:pythoncalendartest@python.org +SUMMARY: +DESCRIPTION: +LOCATION: +END:VEVENT +END:VCALENDAR +""" + importer = ICSImporter(self.calendar) + importer.import_events_from_text(ical) + + event = Event.objects.get(uid="pythoncalendartest@python.org") + url = reverse("events:event_detail", kwargs={"pk": event.pk, "calendar_slug": self.calendar.slug}) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + event_page = response.content.decode() + self.assertIn("<javascript:alert(1)>", event_page) + self.assertNotIn("", event_page)