npx skills add ...
npx skills add getsentry/sentry --skill sentry-security
npx skills add getsentry/sentry --skill sentry-security
Sentry-specific security review based on real vulnerability history. Use when reviewing Sentry endpoints, serializers, or views for security issues. Trigger keywords: "sentry security review", "check for IDOR", "access control review", "org scoping", "cross-org", "security audit endpoint".
Find security vulnerabilities in Sentry code by checking for the patterns that have caused real vulnerabilities in this codebase.
This skill is Sentry-specific. It encodes patterns from 37 real security patches shipped in the last year — not generic OWASP theory.
Review the code provided by the user (file, diff, or endpoint). Research the codebase as needed to build confidence before reporting.
Report only HIGH and MEDIUM confidence findings. Do not report theoretical issues.
| Confidence | Criteria | Action |
|---|---|---|
| HIGH | Traced the flow, confirmed no check exists | Report with fix |
| MEDIUM | Check may exist but could not confirm | Report as needs verification |
| LOW | Theoretical or mitigated elsewhere | Do not report |
Determine what you're reviewing and load the relevant reference.
| Code Type | Load Reference |
|---|---|
API endpoint (inherits from *Endpoint) | references/endpoint-patterns.md |
| Serializer or form field | references/serializer-patterns.md |
| Email template or HTML rendering | references/output-sanitization.md |
| Token, OAuth, or session handling | references/token-lifecycle.md |
| Role or permission logic | references/privilege-escalation.md |
If the code spans multiple categories, load all relevant references.
Always load references/enforcement-layers.md — it documents where security checks can legitimately live in Sentry's request lifecycle. A check in any layer counts as enforcement.
These are ordered by frequency from the last year of real patches.
The most common vulnerability. An endpoint accepts an ID from the request but does not scope the query by the organization from the URL.
Trace this flow for every ID that comes from the request:
Red flags:
Model.objects.get(id=request.data["something_id"]) — no org scopeModel.objects.filter(id=request.GET["id"]) — no org scopeproject_id from request body/query used directly without Project.objects.filter(id=pid, organization_id=organization.id)OrganizationEndpoint but handler method does not accept or use the organization parameterSafe patterns:
organization_id=organization.id where organization comes from convert_args()self.get_projects() which scopes by org internallyconvert_args()An endpoint or serializer performs a sensitive operation without verifying the user has permission.
Check:
OrganizationEndpoint, ProjectEndpoint, etc.)permission_classes? If not, it inherits the base class default — verify that's appropriate.@login_required or equivalent?A user can assign ownership, modify roles, or escalate access beyond what their role allows.
Check:
OwnerActorField (validates membership), NOT ActorField (allows any actor)team:admin)Token lifecycle gaps that allow unauthorized access.
Check:
organization_id required and validated?User-controlled strings rendered unsafely in emails, markdown, or HTML.
Check:
format_html() vs string concatenation in templatesmark_safe() called on user inputAuthentication state inconsistencies.
Check:
If no checks produced a potential finding, stop and report zero findings. Do not invent issues to fill the report. An empty result is the correct output when the code has no vulnerabilities matching these patterns.
For each potential finding, trace the complete request flow end-to-end. Do not stop at the authentication class — follow into the endpoint handler, then into any business logic classes it delegates to (e.g., Validator, Refresher, GrantExchanger).
A check at ANY layer is enforcement. Before marking HIGH, confirm the check is absent from all layers using the checklist in enforcement-layers.md.
If you cannot confirm the check is absent from every layer, mark the finding as MEDIUM (needs verification), not HIGH.
Cross-flow enforcement for token issuance: For token/credential issuance flows, also check whether the issued credential is blocked at usage time (e.g., determine_access() rejects it at all endpoints in the relevant scope). Classify based on the enforcement scope:
See enforcement-layers.md "Cross-Flow Enforcement."
Non-DRF views: OAuth views are plain Django views — the 7-layer DRF model does not apply to the view itself. Check the view's own decorators and handler logic. But tokens issued by these views are later used at DRF endpoints where the full enforcement chain applies.
[MEDIUM confidence items with explanation of what to verify]
[Areas outside the scope of this review]
## Sentry Security Review: [Component]
### Findings
#### [SENTRY-001] [Title] (Severity: Critical/High/Medium)
- **Category**: [IDOR | Missing Auth | Privilege Escalation | Token | XSS | Auth/MFA]
- **Location**: `path/to/file.py:123`
- **Confidence**: HIGH — confirmed through code tracing
- **Issue**: [What the vulnerability is]
- **Trace**:
1. [Step-by-step trace showing how the vulnerability is reached]
- **Impact**: [What an attacker could do]
- **Fix**:
```python
[Code that fixes the issue — must enforce, not document]
```
Fix suggestions must include actual enforcement code. Never suggest a comment or docstring as a fix.