Inefficient Regular Expression Complexity in GitLab
Description
An issue has been discovered in GitLab CE/EE affecting all versions starting from 9.3 before 16.0.8, all versions starting from 16.1 before 16.1.3, all versions starting from 16.2 before 16.2.2. A Regular Expression Denial of Service was possible via sending crafted payloads which use ProjectReferenceFilter to the preview_markdown endpoint.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
GitLab CE/EE vulnerable to ReDoS via crafted payloads sent to preview_markdown endpoint, causing denial of service.
Vulnerability
All versions of GitLab CE/EE from 9.3 before 16.0.8, 16.1 before 16.1.3, and 16.2 before 16.2.2 contain a regular expression denial of service (ReDoS) vulnerability. The ProjectReferenceFilter component, used in markdown processing, can be triggered by sending specially crafted payloads to the preview_markdown endpoint [1].
Exploitation
An unauthenticated attacker can send crafted HTTP requests containing a malicious payload to the preview_markdown endpoint. The attacker does not need any special privileges or authentication. The payload exploits a regex in ProjectReferenceFilter causing excessive backtracking, leading to CPU exhaustion [1].
Impact
Successful exploitation results in denial of service, making the GitLab instance unresponsive. This can degrade service availability and potentially affect all users of the instance [1].
Mitigation
GitLab has released fixed versions: 16.0.8, 16.1.3, and 16.2.2. Users should upgrade to these versions or later. No workaround is mentioned; upgrading is the recommended action [1].
AI Insight generated on May 24, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
4cpe:2.3:a:gitlab:gitlab:*:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:gitlab:gitlab:*:*:*:*:*:*:*:*range: 9.3
- (no CPE)range: >=9.3 <16.0.8 || >=16.1 <16.1.3 || >=16.2 <16.2.2
- Range: >=9.3 <16.0.8 || >=16.1 <16.1.3 || >=16.2 <16.2.2
Patches
0No patches discovered yet.
Vulnerability mechanics
Root cause
"Catastrophic backtracking in the `ProjectReferenceFilter` regex pattern due to the alternation `(>|>)` at the end, which causes the regex engine to exhaustively search for non-existent trailing characters in crafted payloads."
Attack vector
An unauthenticated attacker sends crafted payloads to the `preview_markdown` endpoint of any public group. The payload (e.g., `"mailto:" + "a-" * 499_000 + "@aaaaaaaa..aaaaaaaa.example.com"`) triggers severe backtracking in the `ProjectReferenceFilter` regex because the regex engine repeatedly tries to match the absent `>` or `>` suffix [ref_id=1]. Each request exhausts one CPU core for up to 60 seconds (the default timeout), and sustained requests at a tuned rate (e.g., 1 RPS) quickly consume all worker processes, causing 500 errors and complete denial of service for all users, including authenticated sessions and CI runners [ref_id=1].
Affected code
The vulnerability resides in `lib/banzai/filter/references/project_reference_filter.rb` and `app/models/project.rb`. The `ProjectReferenceFilter` uses `Project.markdown_reference_pattern`, which builds a regex by combining `reference_pattern`, `reference_postfix` (`>`), and `reference_postfix_escaped` (`>`). The resulting regex causes catastrophic backtracking when the input lacks the trailing `>` or `>` characters [ref_id=1].
What the fix does
The advisory does not include a published patch diff, but the recommended fix is to rewrite the regex pattern `(>|>)` to prevent catastrophic backtracking while maintaining consistency with other features [ref_id=1]. A typical approach would be to use an atomic group or possessive quantifier to avoid the regex engine's exponential backtracking when the trailing characters are absent. No official patch is shown in the provided bundle.
Preconditions
- configA public group must exist on the GitLab instance so the unauthenticated attacker can access its preview_markdown endpoint
- authThe attacker must obtain a valid CSRF token and session cookie for the public group page (both obtainable without authentication)
- networkThe attacker must be able to send HTTP POST requests to the /groups/[GROUP_NAME]/preview_markdown endpoint
- inputThe attacker must supply a crafted payload string (e.g., 'mailto:' + 'a-' * 499_000 + '@' + many 'a' chars + '.example.com') that triggers backtracking in the ProjectReferenceFilter regex
Reproduction
1. Set up a GitLab instance, create an account, and create a public group. Note the group name and base URL with scheme. 2. As an unauthenticated user, browse to the public group page and capture the `csrf-token` meta tag value and the `_gitlab_session` cookie value. 3. Prepare the payload file `ProjectReferenceFilter_ReDoS_payload.json` (generated by Ruby code `"mailto:" + "a-" * 499_000 + "@aaaaaaaa..aaaaaaaa.example.com"`). 4. Run the following command (substituting the captured values) to send 1 request per second: `ruby -e 'while true do p spawn("curl --header Content-Type:application/json --header X-CSRF-Token:[CSRF_TOKEN_VALUE] --header Cookie:_gitlab_session=[SESSION_VALUE] --data @ProjectReferenceFilter_ReDoS_payload.json [BASE_URL_WITH_SCHEME]groups/[PUBLIC_GROUP_NAME]/preview_markdown"); sleep 1; end'` 5. Confirm significant CPU consumption; the instance becomes unresponsive within tens of seconds to minutes [ref_id=1].
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2- hackerone.com/reports/1963255mitretechnical-descriptionexploitpermissions-required
- gitlab.com/gitlab-org/gitlab/-/issues/416225mitreissue-trackingpermissions-required
News mentions
1- GitLab Security Release: 16.2.2, 16.1.3, and 16.0.8GitLab Security Releases · Aug 1, 2023