# Unauthenticated IP allowlist bypass when accessing job artifacts through gitlab pages at `{group_id}.gitlab.io`

GitLab Pages endpoint serves job artifacts of IP-restricted groups without enforcing the IP allowlist, leaking artifacts to unauthenticated users who know the job ID.

- Payout: hidden
- Severity: medium
- Program: GitLab
- Found by: joaxcar
- Disclosed: 2022-09-22
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/1591412
- Library page: https://bugbountylibrary.com/r/h1%3A1591412
- Tags: area:web domain:web impact:data-leak impact:internal-access kind:bounty platform:hackerone sev:medium technique:source-review vuln:access-control vuln:auth-bypass vuln:info-disclosure

**Target:** GitLab Pages artifact preview endpoint ({group_id}.gitlab.io)
**Root cause:** The gitlab.io Pages artifact preview endpoint does not apply the group's IP allowlist restriction that the main gitlab.com artifact endpoints enforce, so artifacts remain reachable from any IP.
**Steps:**
1. Create public group `group01` (Premium) with public project `project01` containing `hidden.json` and a `.gitlab-ci.yml` with `artifacts: paths: [./]`.
2. Run pipeline; note job ID from `https://gitlab.com/group01/project01/-/jobs/<id>/artifacts/browse`.
3. Confirm artifact accessible at `https://gitlab.com/group01/project01/-/jobs/<id>/artifacts/file/hidden.json`.
4. Set group IP allowlist to `1.1.1.1`; gitlab.com artifact URLs now return 404.
5. Request `https://group01.gitlab.io/-/project01/-/jobs/<id>/artifacts/hidden.json` — content returned.
6. Repeat unauthenticated/logged-out — artifact still served.
**How found:** Researcher read the IP-restriction docs noting caveats, observed that the Pages HTML artifact preview feature serves the complete artifact, and hypothesized the gitlab.io domain would not enforce the group IP allowlist — confirmed by comparing gitlab.com vs gitlab.io responses after enabling the restriction.
**Exploitation:** Attacker obtains a job ID (e.g. via pipeline-finished email notifications to a user on the IP-restricted project, or other ID leaks), then fetches `https://{group_id}.gitlab.io/-/{project}/-/jobs/{job_id}/artifacts/{file}` from any IP without authentication to read the full artifact.
**Insight:** When a product enforces an access control on its primary domain, check alternate serving domains (Pages/CDN/preview subdomains) that render the same resource — they often skip the middleware. Artifact preview features that 'render HTML' may expose the entire artifact tree.
