sentry-security

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Sentry Security Review

Sentry安全审查

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.
通过检查曾在该代码库中引发真实漏洞的模式,找出Sentry代码中的安全漏洞。
本技能是Sentry专属的,它整合了过去一年发布的37个真实安全补丁中的模式——而非通用的OWASP理论。

Scope

审查范围

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.
ConfidenceCriteriaAction
HIGHTraced the flow, confirmed no check existsReport with fix
MEDIUMCheck may exist but could not confirmReport as needs verification
LOWTheoretical or mitigated elsewhereDo not report
审查用户提供的代码(文件、差异或端点)。在报告前,根据需要研究代码库以确保结论可靠。
仅报告可信度的发现。请勿报告理论性问题。
可信度判定标准处理动作
追踪了完整流程,确认不存在检查机制附带修复方案进行报告
可能存在检查机制但无法确认标记为需验证后报告
仅理论上存在风险或已在其他环节缓解不进行报告

Step 1: Classify the Code

步骤1:代码分类

Determine what you're reviewing and load the relevant reference.
Code TypeLoad Reference
API endpoint (inherits from
*Endpoint
)
${CLAUDE_SKILL_ROOT}/references/endpoint-patterns.md
Serializer or form field
${CLAUDE_SKILL_ROOT}/references/serializer-patterns.md
Email template or HTML rendering
${CLAUDE_SKILL_ROOT}/references/output-sanitization.md
Token, OAuth, or session handling
${CLAUDE_SKILL_ROOT}/references/token-lifecycle.md
Role or permission logic
${CLAUDE_SKILL_ROOT}/references/privilege-escalation.md
If the code spans multiple categories, load all relevant references.
Always load
${CLAUDE_SKILL_ROOT}/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.
确定审查对象,并加载相关参考文档。
代码类型加载的参考文档
API端点(继承自
*Endpoint
${CLAUDE_SKILL_ROOT}/references/endpoint-patterns.md
序列化器或表单字段
${CLAUDE_SKILL_ROOT}/references/serializer-patterns.md
邮件模板或HTML渲染
${CLAUDE_SKILL_ROOT}/references/output-sanitization.md
Token、OAuth或会话处理
${CLAUDE_SKILL_ROOT}/references/token-lifecycle.md
角色或权限逻辑
${CLAUDE_SKILL_ROOT}/references/privilege-escalation.md
如果代码涵盖多个类别,请加载所有相关参考文档。
必须加载
${CLAUDE_SKILL_ROOT}/references/enforcement-layers.md
—— 该文档记录了Sentry请求生命周期中安全检查机制的合法存在位置。任何环节的检查都视为有效防护。

Step 2: Check for the Top 6 Vulnerability Classes

步骤2:检查六大漏洞类别

These are ordered by frequency from the last year of real patches.
以下按去年真实补丁的出现频率排序。

Check 1: Cross-Org Object Access (IDOR) — 9 patches last year

检查1:跨组织对象访问(IDOR)——去年有9个相关补丁

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:
1. Where does the ID enter? (query param, request body, URL kwarg)
2. Where is it used in an ORM query?
3. Between (1) and (2), is the query scoped by organization_id or project_id
   from the URL (NOT from the request body)?
Red flags:
  • Model.objects.get(id=request.data["something_id"])
    — no org scope
  • Model.objects.filter(id=request.GET["id"])
    — no org scope
  • project_id
    from request body/query used directly without
    Project.objects.filter(id=pid, organization_id=organization.id)
  • Endpoint inherits
    OrganizationEndpoint
    but handler method does not accept or use the
    organization
    parameter
Safe patterns:
  • Query includes
    organization_id=organization.id
    where
    organization
    comes from
    convert_args()
  • Uses
    self.get_projects()
    which scopes by org internally
  • Object is fetched via URL kwargs resolved by
    convert_args()
  • Unscoped query is a guard that only raises an error (never returns data), AND a downstream query in the same flow IS org-scoped and raises the same error — no differential behavior means no information leak
这是最常见的漏洞类型。端点接受请求中的ID,但未按URL中的组织信息限定查询范围。
追踪请求中每个ID的流转路径:
1. ID从何处传入?(查询参数、请求体、URL关键字参数)
2. ID在ORM查询中如何使用?
3. 在(1)和(2)之间,查询是否通过URL中的organization_id或project_id进行范围限定(**禁止**使用请求体中的值)?
风险信号:
  • Model.objects.get(id=request.data["something_id"])
    —— 未按组织限定范围
  • Model.objects.filter(id=request.GET["id"])
    —— 未按组织限定范围
  • 直接使用请求体/查询参数中的project_id,未通过
    Project.objects.filter(id=pid, organization_id=organization.id)
    进行校验
  • 端点继承了
    OrganizationEndpoint
    ,但处理方法未接收或使用
    organization
    参数
安全模式:
  • 查询中包含
    organization_id=organization.id
    ,其中
    organization
    来自
    convert_args()
  • 使用
    self.get_projects()
    ,该方法内部已按组织限定范围
  • 通过
    convert_args()
    解析的URL关键字参数获取对象
  • 未限定范围的查询仅用于抛出错误(绝不返回数据),且同一流程中的下游查询已按组织限定范围并抛出相同错误——无差异化行为则不存在信息泄露风险

Check 2: Missing Authorization Checks — 10 patches last year

检查2:缺失授权检查——去年有10个相关补丁

An endpoint or serializer performs a sensitive operation without verifying the user has permission.
Check:
  • Does the endpoint inherit from the right base class? (
    OrganizationEndpoint
    ,
    ProjectEndpoint
    , etc.)
  • Does it declare
    permission_classes
    ? If not, it inherits the base class default — verify that's appropriate.
  • For serializer fields that reference other objects: do they validate the user can access those objects?
  • For Django views (not DRF): is there a
    @login_required
    or equivalent?
端点或序列化器执行敏感操作时,未验证用户是否具备相应权限。
检查要点:
  • 端点是否继承了正确的基类?(如
    OrganizationEndpoint
    ProjectEndpoint
    等)
  • 是否声明了
    permission_classes
    ?如果没有,则继承基类的默认配置——需验证该配置是否合适。
  • 对于引用其他对象的序列化器字段:是否验证了用户有权访问这些对象?
  • 对于Django视图(非DRF):是否添加了
    @login_required
    或等效装饰器?

Check 3: Privilege Escalation / Role Abuse — 3 patches last year

检查3:权限提升/角色滥用——去年有3个相关补丁

A user can assign ownership, modify roles, or escalate access beyond what their role allows.
Check:
  • Owner/assignee fields: uses
    OwnerActorField
    (validates membership), NOT
    ActorField
    (allows any actor)
  • Role modification endpoints: verify the requesting user's role is >= the target role
  • Team assignment: verify the user is a member of the target team (or has
    team:admin
    )
用户可分配所有权、修改角色,或获得超出其角色权限的访问能力。
检查要点:
  • 所有者/经办人字段:是否使用
    OwnerActorField
    (验证成员身份),而非
    ActorField
    (允许任何主体)
  • 角色修改端点:验证请求用户的角色权限是否不低于目标角色
  • 团队分配:验证用户是目标团队的成员(或拥有
    team:admin
    权限)

Check 4: Token / Session Security — 5 patches last year

检查4:Token/会话安全——去年有5个相关补丁

Token lifecycle gaps that allow unauthorized access.
Check:
  • Token refresh: is the application's active status checked before granting a refresh?
  • Org-level tokens: is
    organization_id
    required and validated?
  • Member status: is the member's enabled/disabled status checked before granting tokens?
  • Impersonation: are impersonated sessions rate-limited?
Token生命周期中的漏洞可能导致未授权访问。
检查要点:
  • Token刷新:在允许刷新前,是否检查了应用的活跃状态?
  • 组织级Token:是否要求并验证
    organization_id
  • 成员状态:在发放Token前,是否检查了成员的启用/禁用状态?
  • 模拟登录:模拟会话是否受到速率限制?

Check 5: Output Sanitization (XSS/HTML Injection) — 4 patches last year

检查5:输出内容净化(XSS/HTML注入)——去年有4个相关补丁

User-controlled strings rendered unsafely in emails, markdown, or HTML.
Check:
  • User display names, team names, org names used in email templates: are they sanitized?
  • Markdown rendering: is custom CSS or HTML allowed through?
  • format_html()
    vs string concatenation in templates
  • mark_safe()
    called on user input
用户可控的字符串在邮件、Markdown或HTML中被不安全地渲染。
检查要点:
  • 邮件模板中使用的用户显示名、团队名称、组织名称:是否经过净化处理?
  • Markdown渲染:是否允许自定义CSS或HTML?
  • 模板中使用
    format_html()
    而非字符串拼接
  • 对用户输入调用
    mark_safe()

Check 6: Auth/MFA Gaps — 3 patches last year

检查6:认证/MFA漏洞——去年有3个相关补丁

Authentication state inconsistencies.
Check:
  • When removing an authenticator: are recovery codes cleaned up?
  • CSRF token handling: is it synced across tabs/windows?
  • Session invalidation: does removing auth factors properly invalidate sessions?
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.
认证状态不一致的问题。
检查要点:
  • 删除认证器时:是否清理了恢复码?
  • CSRF令牌处理:是否在多个标签页/窗口间同步?
  • 会话失效:移除认证因素后是否正确使会话失效?
如果未发现任何潜在问题,请停止并报告无发现。请勿为了填充报告而编造问题。当代码中不存在符合这些模式的漏洞时,空结果即为正确输出。

Step 3: Trace the Full Enforcement Chain

步骤3:追踪完整防护链

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
).
1. Authentication class   → does authenticate() or authenticate_token() enforce the check?
2. Permission class       → does has_permission() enforce it?
3. convert_args()         → does has_object_permission() / determine_access() enforce it?
4. Access module          → does from_rpc_auth() or from_request() enforce it?
5. Handler method         → does the endpoint handler enforce it?
6. Business logic classes → do downstream classes (Validator, etc.) enforce it?
7. Serializer             → do validate_*() methods enforce it?
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:
  • Centralized enforcement (check runs in a permission class inherited by all endpoints in the affected scope) → the credential is effectively inert → LOW (do not report)
  • Scattered enforcement (only some endpoints or serializers check, others may not) → MEDIUM (report as needs verification)
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.
对于每个潜在发现,追踪完整的请求流转流程。不要在认证类就停止——要跟进到端点处理方法,再到它委托的任何业务逻辑类(如
Validator
Refresher
GrantExchanger
)。
1. 认证类   → authenticate()或authenticate_token()是否执行了检查?
2. 权限类       → has_permission()是否执行了检查?
3. convert_args()         → has_object_permission() / determine_access()是否执行了检查?
4. 访问模块          → from_rpc_auth()或from_request()是否执行了检查?
5. 处理方法         → 端点处理方法是否执行了检查?
6. 业务逻辑类 → 下游类(如Validator等)是否执行了检查?
7. 序列化器             → validate_*()方法是否执行了检查?
任何环节的检查都视为有效防护。 在标记为高可信度前,请使用
enforcement-layers.md
中的清单确认所有环节均无检查机制。
如果无法确认所有环节均无检查机制,请将发现标记为可信度(需验证),而非高可信度。
令牌发放的跨流程防护: 对于令牌/凭证发放流程,还需检查发放的凭证在使用阶段是否被拦截(例如,
determine_access()
在相关范围内的所有端点均拒绝该凭证)。根据防护范围进行分类:
  • 集中式防护(检查机制在受影响范围内所有端点继承的权限类中运行)→ 凭证实际上无法生效 → 可信度(不报告)
  • 分散式防护(仅部分端点或序列化器进行检查,其他可能未检查)→ 可信度(标记为需验证后报告)
详见
enforcement-layers.md
中的“跨流程防护”章节。
非DRF视图: OAuth视图是普通Django视图——DRF的7层模型不适用于视图本身。请检查视图自身的装饰器和处理逻辑。但这些视图发放的令牌后续会在DRF端点使用,此时完整防护链模型适用。

Step 4: Report Findings

步骤4:报告发现

markdown
undefined
markdown
undefined

Sentry Security Review: [Component]

Sentry安全审查:[组件名称]

Findings

发现的问题

[SENTRY-001] [Title] (Severity: Critical/High/Medium)

[SENTRY-001] [标题](严重程度:关键/高/中)

  • 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]

- **Precedent**: [Similar past fix if applicable, e.g. "Similar to #104990 PromptsActivity IDOR"]
  • 类别:[IDOR | 缺失认证检查 | 权限提升 | Token安全 | XSS注入 | 认证/MFA漏洞]
  • 位置
    path/to/file.py:123
  • 可信度:高 —— 通过代码追踪确认
  • 问题描述:[漏洞具体内容]
  • 流转路径:
    1. [逐步展示漏洞触发路径]
  • 影响:[攻击者可实施的操作]
  • 修复方案:
    python
    [修复代码——必须是可执行的防护逻辑,而非文档说明]

- **参考案例**:[类似的过往修复,例如“与#104990 PromptsActivity IDOR漏洞修复类似”]

Needs Verification

需验证项

[MEDIUM confidence items with explanation of what to verify]
[中可信度问题,说明需要验证的内容]

Not Reviewed

未审查范围

[Areas outside the scope of this review]

Fix suggestions must include actual enforcement code. Never suggest a comment or docstring as a fix.
[本次审查未覆盖的区域]

修复建议必须包含实际的防护代码。切勿建议仅添加注释或文档字符串作为修复方案。