Skip to content

Issue-Close Spoofing Persists via Activity-Feed Flooding after Patch

⚠️ Please read the process on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.

HackerOne report #3140313 by pwnie on 2025-05-12, assigned to @greg:

Report | How To Reproduce

Report

Summary

The recent patch to ProcessCommitWorker verifies that the current user (the authenticated pusher) is allowed to close an issue. However, it still writes the commit author into issue.closed_by. Because Git author data can be forged, an attacker can:

  1. Grant the victim the necessary permission by adding them to the attacker-controlled project (e.g., Developer role).
  2. Forge commits that reference “Close # x” while spoofing the victim’s name + email in the author field.

The permission check passes—because the victim does have close rights in that project—so the issue really closes, but the event is logged as if the victim performed the action. The attacker can repeat this indefinitely, creating hundreds or thousands of “Closed issue” entries under the victim’s public profile and contribution graph.


Steps to Reproduce
  1. Set-up
    Attacker creates a public project A.
    Attacker invites Victim as Developer (or higher), conferring issue-close rights.

  2. Seed Issues
    Attacker opens many trivial issues in project A (#1 … #N).

  3. Forge & Push Commits

    git clone ATTACKER_REPO_URL  
    cd ATTACKER_REPO  
    for i in $(seq 1 N); do  
        echo $i > junk$i  
        git add junk$i  
        GIT_AUTHOR_NAME="Victim" \  
        GIT_AUTHOR_EMAIL="victim@example.com" \  
        git commit -m "Close #$i"  
    done  
    git push origin main  
  4. Observe

    • All issues #1 … #N close successfully.
    • Victim’s profile activity feed shows N “closed issue” events, attributed to Victim, even though Victim never interacted.

Impact
Aspect Result
Integrity Falsifies historical record of who performed project actions.
Reputation Makes Victim appear responsible for mass-closing spammy issues, damaging trust.
Denial of Visibility Floods Victim’s activity graph, burying genuine contributions.
Scalability Limited only by attacker’s willingness to create issues; cost is negligible.

Because the closure is legitimate from GitLab’s perspective, victims cannot delete these entries without removing themselves from the project—something they may overlook, and which attackers can re-initiate at any time.


Root Cause

ProcessCommitWorker:

  1. Confirms current_user (the pusher) has can?(:update_issue, issue).
  2. Executes issue.close and sets closed_by = commit.author.

Provided the targeted victim has project membership with the requisite permission, step 1 passes. Step 2 then records the spoofed author.


Suggested Remediation
  • Attribute to the pusher, not the commit author, when auto-closing.
  • If author and pusher differ, mark the event system-generated (“Closed by commit pushed by current_user”).
  • Optionally, notify the impersonated user on first occurrence so they can leave the project or report abuse.
  • Rate-limit auto-close events per user per project to curb flooding.

Severity

High (Integrity + Reputation Abuse)
The vulnerability enables large-scale, permanent manipulation of public user-history without any compromise of their credentials.

Impact

Because the closure is legitimate from GitLab’s perspective, victims cannot delete these entries without removing themselves from the project—something they may overlook, and which attackers can re-initiate at any time.

How To Reproduce

Please add reproducibility information to this section: