Skip to content

Pages Unique domain overwrite risk

Problem

Currently it's possible to hijack pages with unique domain URLs. This is permitted because the current format of pages unique domains is namespace-subgroup-...-project-<RANDOM STRING>. Once this value is known, one can create a namespace (User or Group) with that random string and then a Gitlab Pages for that namespace (https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html#gitlab-pages-default-domain-names), which will have priority on the URL lookup, hijacking the traffic. Example:

Screen_Recording_2023-06-21_at_17.49.15

Proposed solution

  • Instead of using - as the separator on the unique URL, use *.
    • * are valid URL chars, but are not valid as project/group name/path, preventing malicious users to create projects that could end-up with the same URL as a Pages Unique Domain URL.

Notes

Update: 2023-06-26
ProjectSetting.joins(:project)
.where(project_settings: { pages_unique_domain_enabled: true })
.group('projects.visibility_level')
.count
.transform_keys { Gitlab::VisibilityLevel.string_options.key(_1) }

=> {"private"=>241, "public"=>76}

Public projects have higher risk of being attacked.

Update: 2023-06-27
  • Hijacking projects
Project.where(path: ProjectSetting.select("project_settings.pages_unique_domain || '.gitlab.io'"))

=> []
  • Hijacked projects
ProjectSetting
.joins(:project)
.where(projects: { path: "project_settings.pages_unique_domain || '.gitlab.io'" })
.select(:project_id)

=> []
Edited by Kassio Borges