Sentry vulnerable to stored Cross-Site Scripting (XSS)
Description
Sentry is an error tracking and performance monitoring platform. Starting in version 10.0.0 and prior to version 24.7.1, an unsanitized payload sent by an Integration platform integration allows storing arbitrary HTML tags on the Sentry side with the subsequent rendering them on the Issues page. Self-hosted Sentry users may be impacted in case of untrustworthy Integration platform integrations sending external issues from their side to Sentry. A patch has been released in Sentry 24.7.1. For Sentry SaaS customers, no action is needed. This has been patched on July 23, and even prior to the fix, the exploitation was not possible due to the strict Content Security Policy deployed on sentry.io site. For self-hosted users, the maintainers of Sentry strongly recommend upgrading Sentry to the latest version. If it is not possible, one could enable CSP on one's self-hosted installation with CSP_REPORT_ONLY = False (enforcing mode). This will mitigate the risk of cross-site scripting.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
sentryPyPI | >= 10.0.0, < 24.7.1 | 24.7.1 |
Affected products
1Patches
15c679521f153fix(issues): structured issue annotations (#74648)
7 files changed · +22 −19
src/sentry/api/serializers/models/group.py+6 −1 modified@@ -72,6 +72,11 @@ def merge_list_dictionaries( dict1.setdefault(key, []).extend(val) +class GroupAnnotation(TypedDict): + displayName: str + url: str + + class GroupStatusDetailsResponseOptional(TypedDict, total=False): autoResolved: bool ignoreCount: int @@ -145,7 +150,7 @@ class BaseGroupSerializerResponse(BaseGroupResponseOptional): isSubscribed: bool subscriptionDetails: GroupSubscriptionResponseOptional | None hasSeen: bool - annotations: Sequence[str] + annotations: Sequence[GroupAnnotation] class SeenStats(TypedDict):
src/sentry/integrations/mixins/issues.py+1 −1 modified@@ -348,7 +348,7 @@ def map_external_issues_to_annotations(self, external_issues): for ei in external_issues: link = self.get_issue_url(ei.key) label = self.get_issue_display_name(ei) or ei.key - annotations.append(f'<a href="{link}">{label}</a>') + annotations.append({"url": link, "displayName": label}) return annotations
src/sentry/models/platformexternalissue.py+1 −1 modified@@ -35,7 +35,7 @@ def get_annotations_for_group_list(cls, group_list): # group annotations by group id annotations_by_group_id = defaultdict(list) for ei in external_issues: - annotation = f'<a href="{ei.web_url}">{ei.display_name}</a>' + annotation = {"url": ei.web_url, "displayName": ei.display_name} annotations_by_group_id[ei.group_id].append(annotation) return annotations_by_group_id
src/sentry/plugins/bases/issue2.py+4 −6 modified@@ -2,7 +2,6 @@ from django.conf import settings from django.urls import re_path, reverse -from django.utils.html import format_html from rest_framework.request import Request from rest_framework.response import Response @@ -431,11 +430,10 @@ def tags(self, request: Request, group, tag_list, **kwargs): return tag_list tag_list.append( - format_html( - '<a href="{}">{}</a>', - self._get_issue_url_compat(group, issue), - self._get_issue_label_compat(group, issue), - ) + { + "url": self._get_issue_url_compat(group, issue), + "displayName": self._get_issue_label_compat(group, issue), + } ) return tag_list
src/sentry/plugins/bases/issue.py+4 −6 modified@@ -2,7 +2,6 @@ from django import forms from django.conf import settings -from django.utils.html import format_html from rest_framework.request import Request from sentry.models.activity import Activity @@ -312,11 +311,10 @@ def tags(self, request: Request, group, tag_list, **kwargs): return tag_list tag_list.append( - format_html( - '<a href="{}" rel="noreferrer">{}</a>', - self.get_issue_url(group=group, issue_id=issue_id), - self.get_issue_label(group=group, issue_id=issue_id), - ) + { + "url": self.get_issue_url(group=group, issue_id=issue_id), + "displayName": self.get_issue_label(group=group, issue_id=issue_id), + } ) return tag_list
tests/sentry/api/endpoints/test_group_details.py+5 −3 modified@@ -156,7 +156,7 @@ def test_platform_external_issue_annotation(self): response = self.client.get(url, format="json") assert response.data["annotations"] == [ - '<a href="https://example.com/issues/2">Issue#2</a>' + {"url": "https://example.com/issues/2", "displayName": "Issue#2"} ] def test_plugin_external_issue_annotation(self): @@ -172,7 +172,9 @@ def test_plugin_external_issue_annotation(self): url = f"/api/0/issues/{group.id}/" response = self.client.get(url, format="json") - assert response.data["annotations"] == ['<a href="https://trello.com/c/134">Trello-134</a>'] + assert response.data["annotations"] == [ + {"url": "https://trello.com/c/134", "displayName": "Trello-134"} + ] def test_integration_external_issue_annotation(self): group = self.create_group() @@ -191,7 +193,7 @@ def test_integration_external_issue_annotation(self): response = self.client.get(url, format="json") assert response.data["annotations"] == [ - '<a href="https://example.com/browse/api-123">api-123</a>' + {"url": "https://example.com/browse/api-123", "displayName": "api-123"} ] def test_permalink_superuser(self):
tests/sentry/integrations/test_issues.py+1 −1 modified@@ -505,7 +505,7 @@ def test_annotations(self): link = self.installation.get_issue_url(self.external_issue.key) assert self.installation.get_annotations_for_group_list([self.group]) == { - self.group.id: [f'<a href="{link}">{label}</a>'] + self.group.id: [{"url": link, "displayName": label}] } with assume_test_silo_mode(SiloMode.CONTROL):
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-fm88-hc3v-3wwwghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-41656ghsaADVISORY
- github.com/getsentry/self-hosted/releases/tag/24.7.1ghsax_refsource_MISCWEB
- github.com/getsentry/sentry/commit/5c679521f1539eabfb81287bfc30f34dbecd373eghsax_refsource_MISCWEB
- github.com/getsentry/sentry/pull/74648ghsax_refsource_MISCWEB
- github.com/getsentry/sentry/security/advisories/GHSA-fm88-hc3v-3wwwghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.