This page renders the structured benchmark corpus from
packages/docs/src/data/benchmarking/*.json. Add another corpus by dropping a
new JSON file in that directory.
Only validated security vulnerabilities whose vulnerable code lives in the
public getsentry/sentry repository belong here. Private repository findings,
candidate findings, and unrelated product bugs are out of scope.
Each finding carries a Sentry repository SHA and links to the referenced file at
that revision. The current SHA values are inferred from capture timestamps. As
we backfill from the original tickets, fix commits, or raw run logs, replace
them with the most recent SHA known to still contain the vulnerability.
POST /accept-invite lets authenticated users delete arbitrary org members without validating the invite token.
getsentry/sentry@788ba30f1aa4View source
data = { " details " : " unable to accept organization invite " },
elif helper . member_already_exists :
status = status . HTTP_400_BAD_REQUEST , data = { " details " : " member already exists " }
elif not helper . valid_request :
status = status . HTTP_400_BAD_REQUEST ,
data = { " details " : " unable to accept organization invite " },
DSN lookup leaks project metadata to org members without access to the project.
getsentry/sentry@2d929588e20bView source
permission_classes = ( OrganizationDetectorPermission ,)
InternalEAFeaturesEndpoint is reachable by authenticated users instead of requiring org:admin.
getsentry/sentry@2d929588e20bView source
class InternalEAFeaturesEndpoint ( Endpoint ):
OAuth /userinfo returns PII for tokens tied to inactive users or disabled OAuth apps.
getsentry/sentry@2d929588e20bView source
class OAuthUserInfoEndpoint ( Endpoint ):
" GET " : ApiPublishStatus . PRIVATE ,
owner = ApiOwner . ENTERPRISE
authentication_classes = ()
OAuth /userinfo looks up plaintext token values, bypassing the hashed-token path.
getsentry/sentry@2d929588e20bView source
access_token = auth_header [ 1 ]. decode ( " utf-8 " )
token_details = ApiToken . objects . get ( token = access_token )
except ApiToken . DoesNotExist :
raise BearerTokenInvalid ()
Plugin deprecation info enumerates project rules and groups without per-project access checks.
getsentry/sentry@2d929588e20bView source
owner = ApiOwner . ECOSYSTEM
def get ( self , request , organization , plugin_slug ):
Returns a list of objects that are affected by a plugin deprecation. Objects could be issues or alert rules or both
pparam: organization, plugin_slug
# Plugins in the db are stored in lowercase but there is not guarantee that's how the customer will call the API
plugin = plugin_slug . lower ()
plugin_projects = Project . objects . filter (
status = ObjectStatus . ACTIVE ,
Release threshold index returns every org's rows when projects_list resolves empty.
getsentry/sentry@2d929588e20bView source
def get ( self , request : Request , organization : Organization ) -> HttpResponse :
validator = ReleaseThresholdIndexGETValidator (
data = request . query_params ,
if not validator . is_valid ():
return Response ( validator . errors , status = 400 )
environments_list = self . get_environments ( request , organization )
projects_list = self . get_projects ( request , organization )
SYSTEM_OPTIONS_ALLOWLIST behaves as a substring match because of a missing comma.
getsentry/sentry@2d929588e20bView source
SYSTEM_OPTIONS_ALLOWLIST = (
# Used during setup before the superadmin role with the options.admin permission is authed
class SystemOptionsEndpoint ( Endpoint ):
" GET " : ApiPublishStatus . PRIVATE ,
" PUT " : ApiPublishStatus . PRIVATE ,
Unescaped transaction name in root-cause analysis enables Sentry search filter injection.
getsentry/sentry@fbecd17d210cView source
snuba_params = snuba_params ,
selected_columns = selected_columns ,
query = f 'event.type:transaction transaction:" { transaction } "' ,
PUT /system/options/ logs cleartext option values, including credentials.
getsentry/sentry@fbecd17d210cView source
options . set ( k , v , channel = options . UpdateChannel . APPLICATION )
" ip_address " : request . META [ " REMOTE_ADDR " ],
" user_id " : request . user . id ,
Jira install webhook does not bind verified JWT iss to body clientKey; partial fix left residual replay risk.
getsentry/sentry@9fc06de579fbView source
def post ( self , request : Request , * args , ** kwargs ) -> Response :
with IntegrationPipelineViewEvent (
interaction_type = IntegrationPipelineViewType . VERIFY_INSTALLATION ,
domain = IntegrationDomain . PROJECT_MANAGEMENT ,
provider_key = self . provider ,
). capture () as lifecycle :
token = self . get_token ( request )
lifecycle . record_failure ( ProjectManagementFailuresReason . INSTALLATION_STATE_MISSING )
MS Teams action submission does not scope the target group to the integration organization.
getsentry/sentry@9fc06de579fbView source
def _handle_action_submitted ( self , request : Request ) -> Response :
channel_data = data [ " channelData " ]
tenant_id = channel_data [ " tenant " ][ " id " ]
payload = data [ " value " ][ " payload " ]
group_id = payload [ " groupId " ]
integration_id = payload [ " integrationId " ]
user_id = data [ " from " ][ " id " ]
PerforceIntegration.get_config_data exposes the Perforce password to any org member with org:read.
getsentry/sentry@9fc06de579fbView source
def get_config_data ( self ) -> Mapping [ str , Any ]:
Get current configuration values for the integration.
This is called by the serializer to populate the form fields with existing values.
Since we store credentials in integration.metadata (not org_integration.config),
we override the base implementation to read from metadata.
Dictionary of current configuration values that will be used to populate
the form fields defined in get_organization_config()
SlackOptionsLoadEndpoint discloses any project's teams and members across tenants.
getsentry/sentry@9fc06de579fbView source
class SlackOptionsLoadEndpoint ( Endpoint ):
owner = ApiOwner . ECOSYSTEM
" POST " : ApiPublishStatus . PRIVATE ,
authentication_classes = ()
slack_request_class = SlackOptionsLoadRequest
Replays data_export_notifications lets any authenticated user trigger arbitrary GCS transfer jobs.
getsentry/sentry@9fc06de579fbView source
class DataExportNotificationsEndpoint ( Endpoint ):
""" PubSub notifications endpoint. """
owner = ApiOwner . DATA_BROWSING
publish_status = { " POST " : ApiPublishStatus . PRIVATE }
permission_classes = ( SentryIsAuthenticated ,)
def post ( self , request : Request ) -> Response :
retry_transfer_job_run ( request . data , request_run_transfer_job )
return Response ( "" , status = 200 )
Replay DELETE accepts project:read, letting read-only members delete replays.
getsentry/sentry@9fc06de579fbView source
class ReplayDetailsPermission ( ProjectPermission ):
" GET " : [ " project:read " , " project:write " , " project:admin " ],
" POST " : [ " project:write " , " project:admin " ],
" PUT " : [ " project:write " , " project:admin " ],
" DELETE " : [ " project:read " , " project:write " , " project:admin " ],
Preprod snapshot GET/DELETE skips has_project_access, enabling cross-team read and destroy.
getsentry/sentry@9fc06de579fbView source
def delete ( self , request : Request , organization : Organization , snapshot_id : str ) -> Response :
if not settings . IS_DEV and not features . has (
" organizations:preprod-snapshots " , organization , actor = request . user
return Response ({ " detail " : " Feature not enabled " }, status = 403 )
artifact = PreprodArtifact . objects . select_related ( " project " ). get (
id = snapshot_id , project__organization_id = organization . id
except ( PreprodArtifact . DoesNotExist , ValueError ):
return Response ({ " detail " : " Snapshot not found " }, status = 404 )
Pinned-search PUT overwrites another user's GroupSearchView when caller starred it at position 0.
getsentry/sentry@9fc06de579fbView source
# This entire endpoint will be removed once custom views are GA'd
first_starred_view = GroupSearchViewStarred . objects . filter (
organization = organization , user_id = request . user . id , position = 0
default_view = first_starred_view . group_search_view
default_view . query = result [ " query " ]
default_view . query_sort = result [ " sort " ]
ControlAccessService.can_override_sso_as_owner excludes by the wrong primary key, creating a narrow SSO bypass risk.
getsentry/sentry@9fc06de579fbView source
""" If an owner is trying to gain access, allow bypassing SSO if there are no
other owners with SSO enabled.
member_role = OrganizationMemberMapping . objects . get (
organizationmember_id = member . id , organization_id = member . organization_id
except OrganizationMemberMapping . DoesNotExist :
Account-merge endpoint never enforces verification-code expiry or single-use.
getsentry/sentry@9fc06de579fbView source
token = models . CharField ( max_length = 64 , default = generate_token )
expires_at = models . DateTimeField ( default = generate_expires_at )
db_table = " sentry_user_verification_codes_temp "
__repr__ = sane_repr ( " user_id " , " token " )
def regenerate_token ( self ) -> None :
self . token = generate_token ()
self . refresh_expires_at ()
Codecov repository token regeneration accepts org:read for destructive token rotation.
getsentry/sentry@9fc06de579fbView source
class RepositoryTokenRegeneratePermission ( OrganizationPermission ):
" GET " : [ " org:read " , " org:write " , " org:admin " ],
" POST " : [ " org:read " , " org:write " , " org:admin " ],
ExploreSavedQueryVisitEndpoint.post skips check_object_permissions.
getsentry/sentry@9fc06de579fbView source
class ExploreSavedQueryVisitEndpoint ( ExploreSavedQueryBase ):
" POST " : ApiPublishStatus . PRIVATE ,
def has_feature ( self , organization , request ):
" organizations:visibility-explore-view " , organization , actor = request . user
def post ( self , request : Request , organization , query ) -> Response :
Flag webhook signing-secret POST allows org:read members to plant first-time secrets.
getsentry/sentry@9fc06de579fbView source
def post ( self , request : Request , organization : Organization ) -> Response :
validator = FlagWebhookSigningSecretValidator ( data = request . data )
if not validator . is_valid ():
return self . respond ( validator . errors , status = 400 )
# these scopes can always update or post secrets
has_permission = request . access . has_scope ( " org:write " ) or request . access . has_scope (
Sentry App alert-rule trigger dispatch does not verify the installation belongs to the caller's org.
getsentry/sentry@9fc06de579fbView source
return Response ( uuid_context , status = 202 )
created_alert_rule_ui_component = trigger_sentry_app_action_creators_for_issues (
except SentryAppBaseError as e :
ExternalTeamDetailsEndpoint scopes only by org, allowing cross-team modify, delete, and reparent.
getsentry/sentry@9fc06de579fbView source
owner = ApiOwner . ENTERPRISE
organization_id_or_slug : int | str ,
team_id_or_slug : int | str ,
UnlinkIdentityView deletes identities by external_id without proving caller ownership.
getsentry/sentry@9fc06de579fbView source
class UnlinkIdentityView ( IdentityLinkageView , ABC ):
def confirmation_template ( self ) -> str :
return " sentry/auth-unlink-identity.html "
def no_identity_template ( self ) -> str | None :
""" Optional page to show if identities were not found. """
Slack action handler get_rule fetches Rule by ID without org scoping; exploitability is narrowed to rule-ID enumeration.
getsentry/sentry@9fc06de579fbView source
slack_request : SlackActionRequest , organization : Organization , group_type : int
from sentry . notifications . notification_action . utils import should_fire_workflow_actions
""" Get the rule that fired """
rule_id = slack_request . callback_data . get ( " rule " )
get_shared_for_org can bypass the target org's disable_shared_issues flag through slug confusion.
getsentry/sentry@9fc06de579fbView source
data = { " details " : " unable to accept organization invite " },
elif helper . member_already_exists :
status = status . HTTP_400_BAD_REQUEST , data = { " details " : " member already exists " }
elif not helper . valid_request :
status = status . HTTP_400_BAD_REQUEST ,
data = { " details " : " unable to accept organization invite " },
Metric-alert team-target lookup is unscoped while user-target lookup is scoped.
getsentry/sentry@9fc06de579fbView source
dcgas = DataConditionGroupAction . objects . filter (
action__in = [ a . id for a in user_actions ]
). select_related ( " condition_group " )
dcga . action_id : dcga . condition_group . organization_id for dcga in dcgas
org_members = OrganizationMember . objects . filter (
OrganizationPreprodArtifactApprove is missing has_project_access.
getsentry/sentry@9fc06de579fbView source
class OrganizationPreprodArtifactApproveEndpoint ( OrganizationEndpoint ):
owner = ApiOwner . EMERGE_TOOLS
" POST " : ApiPublishStatus . EXPERIMENTAL ,
permission_classes = ( OrganizationReleasePermission ,)
def post ( self , request : Request , organization : Organization , artifact_id : str ) -> Response :
feature_type_str = request . data . get ( " feature_type " )
if feature_type_str not in FEATURE_TYPE_MAP :
{ " detail " : f "feature_type must be one of: { ' , ' . join ( FEATURE_TYPE_MAP . keys ()) } " },
Public preprod size analysis misses has_project_access on head and base artifacts.
getsentry/sentry@9fc06de579fbView source
Retrieve size analysis results for a given artifact.
Returns size metrics including download size, install size, and optional insights.
When a base artifact exists (either from commit comparison or via the `baseArtifactId` parameter),
comparison data showing size differences is included.
The response `state` field indicates the analysis status:
- `PENDING`: Analysis has not started yet.
- `PROCESSING`: Analysis is currently running.
- `FAILED` / `NOT_RAN`: Analysis did not complete; `errorCode` and `errorMessage` are included.
- `COMPLETED`: Analysis finished successfully with full size data.
ProjectKey RPC service drops organization_id; a reachable AWS Lambda integration config path can leak cross-org DSN material.
getsentry/sentry@7f41cc502faaView source
self , organization_id : int , project_id : int , role : ProjectKeyRole
) -> RpcProjectKey | None :
return self . _get_project_key ( project_id = project_id , role = role )
def get_default_project_key (
self , * , organization_id : int , project_id : int
) -> RpcProjectKey | None :
project = Project . objects . get_from_cache ( id = project_id )
replay_counts issue.id branch overwrites snuba_params.projects, bypassing project access scoping.
getsentry/sentry@9fc06de579fbView source
if select_column == " replay_id " :
# just return a mapping of replay_id:replay_id instead of hitting the dataset.
for replay_id in column_value :
# raises ValueError if invalid. Strips '-'
replay_id = uuid . UUID ( hex = replay_id , version = 4 ). hex
identity_map [ replay_id ] = [ replay_id ]
# The client may or may not have narrowed the request by project-id. We have a
Seer autofix run_id is not bound to group in handoff and continue paths.
getsentry/sentry@9fc06de579fbView source
if not group.organization.get_option(
"sentry:enable_seer_coding", default=ENABLE_SEER_CODING_DEFAULT
raise PermissionDenied("Code generation is disabled for this organization")
repo_definitions: list[SeerRepoDefinition] = []
if features.has("organizations:seer-project-settings-read-from-sentry", group.organization):
preference = read_preference_from_sentry_db(group.project)
repo_definitions = preference.repositories
Autofix automation settings GET bypasses get_projects, returning settings for inaccessible projects.
getsentry/sentry@9fc06de579fbView source
def get ( self , request : Request , organization : Organization ) -> Response :
List projects with their autofix automation settings.
:pparam string organization_id_or_slug: the id or slug of the organization.
:qparam string query: Optional search query to filter by project name or slug.
serializer = SeerAutofixSettingGetResponseSerializer (
" query " : request . GET . get ( " query " ),
Supergroups validates org but skips has_project_access on supplied group IDs.
getsentry/sentry@9fc06de579fbView source
permission_classes = ( OrganizationSupergroupsByGroupPermission ,)
def get ( self , request : Request , organization : Organization ) -> Response :
if not features . has ( " organizations:top-issues-ui " , organization , actor = request . user ):
return Response ({ " detail " : " Feature not available " }, status = 403 )
raw_group_ids = request . GET . getlist ( " group_id " )
group_ids = [ int ( gid ) for gid in raw_group_ids ]
Sentry App cell service makes user optional, dropping has_project_access for live callers.
getsentry/sentry@9fc06de579fbView source
class DatabaseBackedSentryAppCellService ( SentryAppCellService ):
installation : RpcSentryAppInstallation ,
user : RpcUser | None = None ,
project_id : int | None = None ,
query : str | None = None ,
GroupEventJsonView checks org scope but not project access before returning event JSON.
getsentry/sentry@9fc06de579fbView source
class SentryAppInstallationExternalIssueActionsEndpoint ( SentryAppInstallationBaseEndpoint ):
Open periods endpoint resolves detector/group with org-only scope and no has_project_access.
getsentry/sentry@9fc06de579fbView source
permission_classes = ( OrganizationDetectorPermission ,)
def get_group_from_detector_id (
self , detector_id : str , organization : Organization
validated_detector_id = to_valid_int_id ( " detectorId " , detector_id )
Detector . objects . with_type_filters ()
. select_related ( " project " )
. get ( id = validated_detector_id )
Workflow detector disconnect skips per-project permission checks on removed connections.
getsentry/sentry@9fc06de579fbView source
def can_edit_detector_workflow_connections ( detector : Detector , request : Request ) -> bool :
Anyone with alert write access to the project can connect/disconnect detectors of any type,
which is slightly different from full edit access which differs by detector type.
return request . access . has_any_project_scope (
detector . project , USER_CREATED_DETECTOR_REQUIRED_SCOPES
DiscoverSavedQueryVisitEndpoint.post skips check_object_permissions.
getsentry/sentry@9fc06de579fbView source
class DiscoverSavedQueryVisitEndpoint ( DiscoverSavedQueryBase ):
" POST " : ApiPublishStatus . PRIVATE ,
def has_feature ( self , organization , request ):
return features . has ( " organizations:discover-query " , organization , actor = request . user )
def post ( self , request : Request , organization , query ) -> Response :
Update last_visited and increment visits counter
InsightsStarredSegment stores user-supplied project_id without org or project access validation.
getsentry/sentry@9fc06de579fbView source
slack_request : SlackActionRequest , organization : Organization , group_type : int
from sentry . notifications . notification_action . utils import should_fire_workflow_actions
""" Get the rule that fired """
rule_id = slack_request . callback_data . get ( " rule " )
InternalRegisteredTemplatesEndpoint is reachable by any authenticated user instead of superuser only.
getsentry/sentry@9fc06de579fbView source
class InternalRegisteredTemplatesEndpoint ( Endpoint ):
owner = ApiOwner . ECOSYSTEM
permission_classes = ( SentryIsAuthenticated ,)
publish_status = { " GET " : ApiPublishStatus . PRIVATE }
def get ( self , request : Request ) -> Response :
response : dict [ str , list [ dict [ str , Any ]]] = defaultdict ( list )
for source , template_cls in template_registry . registrations . items ():
AuthIndexEndpoint.put fail-opens superuser reauth when SaaS runs with SUPERUSER_ORG_ID=None.
getsentry/sentry@6993246259d0View source
validator = AuthVerifyValidator ( data = request . data )
if not ( request . user . is_superuser and request . data . get ( " isSuperuserModal " )):
validator . is_valid ( raise_exception =True )
return Response ({ " detail " : { " code " : MISSING_PASSWORD_OR_U2F_CODE }}, status = 400 )
authenticated = self . _verify_user_via_inputs ( validator , request )
verify_authenticator = False
if not DISABLE_SSO_CHECK_FOR_LOCAL_DEV and not is_self_hosted ():
verify_authenticator = organization_service . check_organization_by_id (
id = SUPERUSER_ORG_ID , only_visible =False
Public preprod install-details resolves artifact by org and returns metadata plus install URLs without project access.
getsentry/sentry@7f41cc502faaView source
# Check if this is an org-level method
if method_name in public_org_seer_method_registry :
Pull-request size-analysis download resolves artifact by org and streams raw size-analysis JSON without project access.
getsentry/sentry@7f41cc502faaView source
artifact = PreprodArtifact . objects . get (
project__organization_id = organization . id ,
except ( PreprodArtifact . DoesNotExist , ValueError ):
raise PreprodArtifactResourceDoesNotExist
cutoff = get_size_retention_cutoff ( organization )
if artifact . date_added < cutoff :
return Response ({ " detail " : " This build's size data has expired. " }, status = 404 )
all_size_metrics = list ( artifact . get_size_metrics ())
WorkflowEngineRuleEndpoint authorizes URL project but resolves workflow-backed rules by org and rule or workflow ID.
getsentry/sentry@7f41cc502faaView source
@ extend_schema ( tags = [ " Alerts " ])
class ProjectRuleDetailsEndpoint ( WorkflowEngineRuleEndpoint ):
Project size-analysis comparison download authorizes URL project but resolves comparisons by org and metric IDs only.
getsentry/sentry@7f41cc502faaView source
comparison_obj = PreprodArtifactSizeComparison . objects . select_related (
" head_size_analysis__preprod_artifact " ,
" base_size_analysis__preprod_artifact " ,
head_size_analysis_id = head_size_metric_id ,
base_size_analysis_id = base_size_metric_id ,
organization_id = project . organization_id ,
except PreprodArtifactSizeComparison . DoesNotExist :
" preprod.size_analysis.compare.api.download.no_comparison_obj " ,
" head_size_metric_id " : head_size_metric_id ,
GitHub install flow accepts unknown installation IDs before trusted webhook sender validation.
getsentry/sentry@7f41cc502faaView source
# has data (e.g. installation_id from a GitHub redirect) that needs
# to be available to pipeline steps.
serializer_cls = pipeline . provider . get_initial_data_serializer_cls ()
CODEOWNERS code-mapping GET resolves config by org and returns raw CODEOWNERS without checking config.project.
getsentry/sentry@7f41cc502faaView source
def serialize ( self , obj , attrs , user , ** kwargs ):
from sentry . api . validators . project_codeowners import build_codeowners_associations
" dateCreated " : obj . date_added ,
Bitbucket Server accepts unsigned public webhooks with no HMAC, shared secret, or IP validation.
getsentry/sentry@7f41cc502faaView source
r " ^organizations/ ( ?P<organization_id> [ ^ / ] + ) /webhook/ ( ?P<integration_id> \d + ) /$ " ,
Data forwarding API returns decrypted provider credentials such as Segment, AWS, and Splunk secrets in config responses.
getsentry/sentry@7f41cc502faaView source
config = EncryptedJSONField ( default = dict )
Sentry App external issue actions accept org:integrations without the event scope used by sibling endpoints.
getsentry/sentry@7f41cc502faaView source
class SentryAppInstallationExternalIssueActionsEndpoint ( SentryAppInstallationBaseEndpoint ):
Relocation retry leaks relocation existence and state before owner or elevated authorization.
getsentry/sentry@7f41cc502faaView source
" POST " : ApiPublishStatus . EXPERIMENTAL ,
permission_classes = ( SentryIsAuthenticated ,)
Public org-level Seer RPC methods can query project-backed data without applying the caller's project access.
getsentry/sentry@7f41cc502faaView source
# Check if this is an org-level method
if method_name in public_org_seer_method_registry :
API authorization listing can expose a fresh OAuth app clientSecret to non-owner grantees during the reveal window.
getsentry/sentry@7f41cc502faaView source
@ register ( ApiApplication )
class ApiApplicationSerializer ( Serializer ):
def serialize ( self , obj , attrs , user , ** kwargs ):
Uptime autodetect fetches robots.txt through raw urllib instead of Sentry's SSRF-safe HTTP stack.
getsentry/sentry@7f41cc502faaView source
Detector anomaly-data endpoint resolves detectors or alert rules by org and returns Seer data without project access.
getsentry/sentry@7f41cc502faaView source
@ extend_schema ( tags = [ " Workflows " ])
class OrganizationDetectorAnomalyDataEndpoint ( OrganizationEndpoint ):
AlertRuleDetector lookup returns detector, alert-rule, and rule mappings without filtering by accessible projects.
getsentry/sentry@7f41cc502faaView source
permission_classes = ( OrganizationDetectorPermission ,)
Newline-capable PR filenames can inject or override $GITHUB_OUTPUT values forwarded to getsentry workflow dispatch.
getsentry/sentry@7f41cc502faaView source
GH_TOKEN : ${{ github.token }}
gh api repos/${{ github.repository }}/pulls/${{ github.event.number }}/files \
Branch name is shell-interpolated in scripts/analyze-styled.ts history analysis commands.
getsentry/sentry@7f41cc502faaView source
logger . debug ( ' Script not found in commit, copying from current version... ' );
// Get the current script content and write it temporarily
client_secret_jwt does not require exp, and the jti replay cache is shorter than token lifetime.
getsentry/sentry@7f41cc502faaView source
payload = jwt . decode ( encoded_jwt , client_secret , algorithms = [ " HS256 " ])
Statsig signed timestamp is included in HMAC input but not checked for freshness.
getsentry/sentry@7f41cc502faaView source
def validate ( self , message_bytes : bytes ) -> bool :
Invalid Bitbucket webhook signatures log the computed HMAC.
getsentry/sentry@7f41cc502faaView source
def is_valid_signature ( body : bytes , secret : str , signature : str ) -> bool :
Invalid Discord signatures log the full decoded body, including possible interaction tokens or user text.
getsentry/sentry@7f41cc502faaView source
verify_signature ( public_key , signature , timestamp , body )
Discord signature timestamp is verified cryptographically but not freshness-checked.
getsentry/sentry@7f41cc502faaView source
self . _validate_identity ()
def authorize ( self ) -> None :
Legacy unsigned GitHub Enterprise webhook bypass trusts attacker-supplied host headers if a legacy host is configured.
getsentry/sentry@7f41cc502faaView source
allowed_legacy_hosts = options . get (
GitHub Enterprise missing-integration and invalid-signature responses differ, enabling installation ID enumeration.
getsentry/sentry@7f41cc502faaView source
return HttpResponse ( status = 400 )
secret = self . get_secret ( event , host )
Atlassian install JWT verification accepts the algorithm from the unverified token header.
getsentry/sentry@7f41cc502faaView source
raise AtlassianConnectValidationError ( " No token parameter " )
headers = jwt . peek_header ( token )
Valid Jira Server webhook JWT is logged and has no expiry.
getsentry/sentry@7f41cc502faaView source
handle_status_change ( integration , data )
except ( ApiError , ObjectDoesNotExist ) as err :
extra . update ({ " token " : token , " error " : str ( err )})
Shared Atlassian helper selects JWT algorithm from the unverified header.
getsentry/sentry@7f41cc502faaView source
raise AtlassianConnectValidationError ( " No token parameter " )
headers = jwt . peek_header ( token )
Legacy OAuth apps allow prefix redirect URI matching.
getsentry/sentry@7f41cc502faaView source
# Then: prefix-only match (legacy behavior). Log on success.
Release webhook token uses uuid1().hex.
getsentry/sentry@7f41cc502faaView source
def _regenerate_token ( self , project ):
Seer RPC HMAC does not bind the URL path.
getsentry/sentry@7f41cc502faaView source
_ , signature_data = signature . split ( " : " , 2 )
Mailgun timestamp and nonce are signed but never freshness- or reuse-checked.
getsentry/sentry@7f41cc502faaView source
class MailgunInboundWebhookView ( View ):
def verify ( self , api_key , token , timestamp , signature ):
Release webhook capability signature is long-lived and embedded in the URL path.
getsentry/sentry@7f41cc502faaView source
class ReleaseWebhookView ( View ):
def verify ( self , plugin_id , project_id , token , signature ):
Heroku release attribution uses unverified email lookup.
getsentry/sentry@7f41cc502faaView source
email = data . get ( " user " , {}). get ( " email " ) or data . get ( " actor " , {}). get ( " email " )
users = user_service . get_many_by_email (
Legacy Jira plugin disables TLS verification while sending Basic Auth.
getsentry/sentry@7f41cc502faaView source
super (). __init__ ( verify_ssl =False )
Jira JQL autocomplete escapes quotes but not backslashes.
getsentry/sentry@7f41cc502faaView source
return self . post ( self . COMMENT_URL . format ( issue_key ), data = { " body " : comment })
def search_issues ( self , project , query ):
Autofix URLs are passed to window.open without protocol or host allowlist.
getsentry/sentry@7f41cc502faaView source
onClick : () => window . open ( url , ' _blank ' ),
Copy-as-curl escapes values but not HTTP method or header names.
getsentry/sentry@7f41cc502faaView source
if ( defined ( data . method ) && data . method !== ' GET ' ) {
result += ' \\\n -X ' + data . method ;
ECharts tooltip interpolates feature flag name and action as HTML.
getsentry/sentry@7f41cc502faaView source
)} </ strong > < / span >< / div > ` ,
` < span class = " tooltip-label-align-start " > < code class = " tooltip-code-no-margin " > $ { data . name } </ code > $ { data . label . formatter ()} </ span > ` ,
CSV macro sanitizer misses tab and carriage-return prefixes.
getsentry/sentry@7f41cc502faaView source
function disableMacros ( value : string | null | boolean | number ) {
ECharts tooltip renders mobile build seriesName from artifact metadata as HTML.
getsentry/sentry@7f41cc502faaView source
const value = ( param . value as number [])[ 1 ] ! ;
const marker = typeof param . marker === ' string ' ? param . marker : '' ;
return ` <div><span class="tooltip-label"> ${ marker } <strong> ${ param . seriesName } </strong></span> ${ formatBytesBase10 ( value ) } </div> ` ;
ECharts treemap tooltip renders uploaded artifact path and name as HTML.
getsentry/sentry@7f41cc502faaView source
const percent = (( value / totalSize ) * 100 ). toFixed ( 2 );
const pathHtml = params . data ?. path
? ` <div style="font-size: 12px; color: ${ theme . tokens . content . secondary } ; line-height: 1.2;"> ${ params . data . path } </div> `
Self-hosted integration domainName can construct https://user@attacker style URLs.
getsentry/sentry@7f41cc502faaView source
const [ domainName , orgName ] = integration . domainName . split ( ' / ' );
Backfill exact vulnerable SHAs from original tickets, fix commits, or raw run
logs.
Add excluded candidate or latent findings only after they are confirmed as
exploitable vulnerabilities in getsentry/sentry.