Skip to content

Require job access in coverage_report before redirecting - #5426

Open
herdiyana256 wants to merge 1 commit into
google:masterfrom
herdiyana256:fix-coverage-report-missing-access
Open

Require job access in coverage_report before redirecting#5426
herdiyana256 wants to merge 1 commit into
google:masterfrom
herdiyana256:fix-coverage-report-missing-access

Conversation

@herdiyana256

@herdiyana256 herdiyana256 commented Aug 14, 2026

Copy link
Copy Markdown

GET /coverage-report resolves a job's coverage report URL and redirects to it without an access check.

The handler only uses @handler.oauth, which reads the Authorization header when present but still runs the handler when it is absent, so the route is reachable without authentication. get_report_url only validates the job and date formats:

def get_report_url(report_type, argument, date):
  ...
  if not data_types.Job.VALID_NAME_REGEX.match(job):
    raise helpers.EarlyExitError('Invalid job name.', 400)
  if not date or not VALID_DATE_REGEX.match(date):
    raise helpers.EarlyExitError('Invalid date.', 400)
  return _get_project_report_url(job, date)

Coverage reports are per-job data, and the other job-scoped handlers already gate on it. For example fuzzer_stats:

access.has_access(fuzzer_name=fuzzer, job_type=job)

Without the same check here, any caller (including an unauthenticated one) can pass an arbitrary job name and get back the coverage report location and the job-to-project mapping for jobs they otherwise cannot access.

Fix adds the job access check right after the name validation:

if not access.has_access(job_type=job):
  raise helpers.AccessDeniedError()

test_no_access covers the denied path; the existing tests mock has_access so they keep exercising the URL logic. This is the same missing-access-check fix proposed for issue_redirector in #5391.

@herdiyana256
herdiyana256 requested a review from a team as a code owner August 14, 2026 18:33
GET /coverage-report resolved a job's coverage report URL and redirected
to it without an access check. The handler only uses @handler.oauth,
which runs even when the Authorization header is absent, so the route is
reachable without authentication, and get_report_url validated only the
job name and date formats.

Coverage reports are per-job data. The other job-scoped handlers already
gate on it (fuzzer_stats uses access.has_access(job_type=...)), so any
caller, including an unauthenticated one, could resolve the coverage
report location and job-to-project mapping for jobs they cannot access.

Add access.has_access(job_type=job) after the job name validation, plus a
test that a caller without access gets AccessDeniedError.
@herdiyana256
herdiyana256 force-pushed the fix-coverage-report-missing-access branch from 3c64c28 to b26d3ad Compare August 14, 2026 18:35
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