Skip to content

Require job access in revisions_info before disclosing component revisions - #5431

Open
herdiyana256 wants to merge 1 commit into
google:masterfrom
herdiyana256:fix-revisions-info-missing-access
Open

Require job access in revisions_info before disclosing component revisions#5431
herdiyana256 wants to merge 1 commit into
google:masterfrom
herdiyana256:fix-revisions-info-missing-access

Conversation

@herdiyana256

@herdiyana256 herdiyana256 commented Aug 21, 2026

Copy link
Copy Markdown

revisions_info reads a job name from the request and returns that job's component revision list, decorated only with @handler.oauth and with no job-access check:

job_type = request.get('job')
# ... straight to resolving the component/revision list, no authorization

The result is per-job build data (the source components, their repo git URLs, and the revisions between two builds), so it should be gated on job access the way coverage_report and fuzzer_stats are. @handler.oauth authenticates the caller but does not authorize an arbitrary job, so without a check any caller could disclose the build composition of a job, and its project, they cannot otherwise access.

from libs import access
from clusterfuzz._internal.datastore import data_types

def get_component_revisions_list(job_type, revision, revision_range):
  if not job_type:
    raise helpers.EarlyExitError('Job name cannot be empty.', 400)
  if not data_types.Job.VALID_NAME_REGEX.match(job_type):
    raise helpers.EarlyExitError('Invalid job name.', 400)
  if not access.has_access(job_type=job_type):
    raise helpers.AccessDeniedError()
  ...

The logic is refactored into get_component_revisions_list, which validates the job name and requires job access before disclosing anything. Adds a regression test for the access-denied path.

…sions

The revisions_info handler is decorated with @handler.oauth, which
authenticates the caller but does not authorize access to a specific job. It
read the `job` request parameter and returned the component/repo/revision list
for that job with no access check, so any authenticated caller could disclose
the build composition (source components, repo URLs and revisions) of an
arbitrary job, including jobs and projects they are not authorized for.

Gate the lookup on access.has_access(job_type=job) and validate the job name,
matching the other job-scoped handlers (coverage_report, fuzzer_stats). The core
logic moves into get_component_revisions_list so the access-denied path is
covered by a unit test.
@herdiyana256
herdiyana256 requested a review from a team as a code owner August 21, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant