Skip to content

Cross-object authorization issue in /testcase-detail/update-issue allows testcase-scoped access to update unrelated issue IDs #5262

@Omar-Khaleel

Description

@Omar-Khaleel

Cross-object authorization issue in /testcase-detail/update-issue

Summary

/testcase-detail/update-issue authorizes access to a testcase, but then performs an issue-tracker update on a request-supplied issueId without first binding that issueId to the testcase’s currently linked issue.

As a result, a user who is authorized to access one testcase can use that testcase-scoped authorization to trigger updates on a different issue ID supplied in the request.

Affected file

src/appengine/handlers/testcase_detail/update_issue.py

Affected flow

  • Handler.post
  • Handler.update_issue

Technical details

The request accepts:

  • testcaseId
  • issueId
  • needsSummaryUpdate

The access-control decision is made for the testcase referenced by testcaseId.

However, the issue update path then uses the request-supplied issueId to fetch and update an issue through the trusted issue-tracker integration.

The relevant behavior is:

  1. Access is checked for the testcase.
  2. The handler accepts issueId from the request.
  3. The issue tracker fetches that supplied issue ID.
  4. The handler updates issue fields and saves the issue.
  5. The testcase is then rebound by setting testcase.bug_information to the supplied issue ID.

This means authorization is established for one object type, the testcase, while the state-changing write is performed on another object, the issue selected from request input.

Expected behavior

Before performing the issue-tracker write, the handler should verify that the request-supplied issueId is already authorized in relation to the testcase.

For example, the handler should require that the supplied issue ID matches the testcase’s existing linked issue or another explicitly allowed issue relationship before applying comments, labels, title changes, or rebinding.

Observed behavior

Runtime validation showed the following sequence:

=== BEFORE ===
testcase bug_information: 1111
target issue title: ORIGINAL_TITLE
target issue labels: {'old-label'}

[GET_ISSUE] issue_id=2002
[SAVE] issue_id=2002
[SAVE] title=POC summary for testcase 1001
[SAVE] labels={'clusterfuzz-label', 'old-label'}
[SAVE] new_comment='POC comment from lowpriv@example.com for testcase 1001'
[TESTCASE_PUT] bug_information=2002
[UPDATE_GROUP_BUG] group_id=None
[HTTP_STATUS] 200
[HTTP_BODY] '{"testcaseId": 1001, "bugInformation": "2002", "groupBugInformation": null}'

=== AFTER ===
testcase bug_information: 2002
testcase put called: True
target issue title: POC summary for testcase 1001
target issue labels: {'clusterfuzz-label', 'old-label'}
target issue comments: ['POC comment from lowpriv@example.com for testcase 1001']

This demonstrates that a request using a testcase initially linked to issue 1111 can supply issueId=2002, resulting in an update to issue 2002 and rebinding of the testcase to 2002.

Security impact

This is a cross-object authorization issue in the issue update flow.

A user with testcase-scoped access can cause the trusted issue-tracker integration to perform state-changing updates on an issue selected from request input, including:

  • adding a generated comment
  • updating the issue title when summary update is enabled
  • applying policy-driven labels
  • rebinding the testcase to the supplied issue ID

Suggested fix

The handler should enforce an authorization/binding check before performing the issue update.

Possible approaches:

  • reject issueId values that do not match the testcase’s existing bug_information or another valid linked issue relationship
  • perform rebinding only after an explicit authorization check for the target issue
  • separate “link testcase to existing issue” from “update issue metadata” so that linking does not automatically grant write authority to the supplied issue
  • ensure comments, title updates, and labels are applied only after the target issue is verified as authorized for that testcase

poc_http_output.txt
poc_update_issue_http.py
poc_update_issue_runtime.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions