Cybersecurity

GitLab Patches Three Authenticated Denial-of-Service Vulnerabilities — CVE-2026-1660, CVE-2025-3922 and CVE-2025-0186

Team Nippysoft
15 min read
GitLab Patches Three Authenticated Denial-of-Service Vulnerabilities — CVE-2026-1660, CVE-2025-3922 and CVE-2025-0186

Three authenticated denial-of-service vulnerabilities in GitLab CE/EE were patched simultaneously on April 22, 2026 — CVE-2026-1660, CVE-2025-3922, and CVE-2025-0186. All three fall under CWE-770 (Allocation of Resources Without Limits or Throttling), meaning GitLab had three separate endpoints where a logged-in attacker could drive the server into resource exhaustion without hitting any effective ceiling.

The timing tells its own story. CVE-2025-0186 was reserved as far back as January 2025, which puts the window between discovery and patch at over 15 months. CVE-2025-3922 followed later in the same year, and CVE-2026-1660 was reserved in January 2026. All three landed in the same coordinated release — a deliberate GitLab practice of batching security fixes that reduces signal value per notification but also avoids broadcasting exploit targets before most operators can respond.

Self-managed GitLab installations carry the full risk here. GitLab.com was already updated before the public disclosure. If you're running an on-premises instance and haven't updated to 18.9.6, 18.10.4, or 18.11.1, your platform is exposed to three distinct availability attack paths — all requiring only a valid authenticated session to trigger.

The April 2026 GitLab Security Release in Context

GitLab's April 22, 2026 security release addressed multiple issues, but CVE-2026-1660, CVE-2025-3922, and CVE-2025-0186 form a coherent cluster worth analyzing together. They share the same root cause classification, the same patch versions, and the same severity score. What they differ in is the attack surface: each one targets a distinct feature area of the GitLab platform.

The common denominator is CWE-770. This weakness describes software that allocates resources — memory, threads, database connections, processing time — in response to user input without enforcing meaningful limits. In authenticated applications, this pattern is particularly dangerous because developers often assume that logged-in users are inherently trustworthy. That assumption collapses the moment an attacker controls the account, or when internal credentials are compromised through an unrelated breach.

All three vulnerabilities share an identical CVSS 3.1 vector: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H. Breaking this down:

  • Network-accessible (AV:N): exploitable remotely over any network connection.
  • Low attack complexity (AC:L): no special conditions or race conditions required.
  • Low privileges (PR:L): only a basic authenticated account is needed — no admin access.
  • No user interaction (UI:N): the attack can be fully automated without tricking another user.
  • High availability impact (A:H): the service can be rendered fully unavailable.

The Medium score of 6.5 reflects the authentication requirement. Remove that barrier and these would score in the High range. But authenticated DoS is still a serious risk in multi-tenant GitLab deployments, in organizations where account creation is open to all employees, or anywhere a single compromised credential can be weaponized.

CVE-2026-1660 — Denial of Service via Issue Import

CVE-2026-1660 targets GitLab's issue import functionality. When users import issues — a legitimate project migration feature — the server processes incoming data without enforcing adequate resource constraints. An authenticated attacker can craft import requests that drive unconstrained resource allocation on the server, degrading or halting availability for every other user on the instance.

The vulnerability affects GitLab CE/EE from version 12.3 through 18.9.5, versions 18.10.0 through 18.10.3, and version 18.11.0. The breadth of the affected range — stretching back to 12.3 — underlines how long this attack surface has existed unaddressed in the codebase.

What the Attack Looks Like in Practice

An attacker with a valid GitLab account creates a project and initiates repeated or oversized issue import operations. Because the server lacks throttling at the processing layer, each request consumes CPU and memory disproportionate to what a legitimate migration would require. Depending on the instance's hardware profile, this can range from noticeable performance degradation to a complete service outage.

Consider a self-managed GitLab instance hosting active CI/CD pipelines: a single attacker account triggers import operations timed against peak pipeline activity. The result is cascading build failures as the GitLab API becomes unresponsive — not because pipelines broke, but because the underlying service is resource-starved. Operations teams chase an infrastructure problem that is actually an application-layer exploit.

The fix is available in 18.9.6, 18.10.4, and 18.11.1. No configuration-only workaround exists. If upgrading immediately is not feasible, restricting issue import permissions to administrator-level roles at the policy level reduces the exploitable population as a temporary measure.

CVE-2025-3922 — GraphQL API Resource Exhaustion

CVE-2025-3922 sits in GitLab's GraphQL API layer. GraphQL is particularly susceptible to resource exhaustion because queries are flexible by design — clients control query depth, field selection, and result volume. Without explicit limits on query complexity or execution cost, a single crafted query can cascade into dozens of database resolver executions.

The affected versions span GitLab CE/EE from 12.4 through 18.9.5, 18.10.0 through 18.10.3, and 18.11.0. This vulnerability was reported through GitLab's HackerOne bug bounty program (report #3098035) and linked to GitLab work item #537422.

Why GraphQL DoS Is an Architectural Problem

REST APIs are naturally constrained: each endpoint does one predictable thing with bounded inputs. GraphQL's flexibility is also its attack surface. A deeply nested query or one requesting enormous result sets forces the server to resolve each node in the graph, compounding resource usage with every additional level. Standard HTTP-level rate limiting at the request count level does not help here — a single request can trigger thousands of resolver executions and consume resources equivalent to hundreds of normal API calls.

This attack category appears consistently in GraphQL security literature under names like "query complexity attack" or "alias batching attack." GitLab's implementation lacked sufficient query cost analysis to prevent authenticated users from deliberately constructing such queries.

Scalability Consideration for Large Instances

For teams running large GitLab deployments — hundreds of projects, active CI pipelines, integrations consuming the GraphQL API — the impact profile of this vulnerability is elevated. A single compromised service account with standard API access can degrade the entire platform. The attack requires no human interaction once scripted, making it straightforward to automate and sustain. For organizations using GitLab's GraphQL API for internal tooling or dashboards, this vulnerability deserves immediate attention even before the full upgrade cycle completes.

CVE-2025-0186 — Discussions Endpoint Denial of Service

CVE-2025-0186 has the oldest reservation date of the three — January 3, 2025 — and targets the discussions endpoint in GitLab CE/EE. This endpoint handles comments and review threads across merge requests, issues, and commit reviews: one of the most actively used surfaces in any collaborative GitLab workflow. An authenticated user can send specially crafted requests to this endpoint to exhaust server resources, again through the CWE-770 pattern of unconstrained allocation.

The affected version range starts from 10.6, making this the broadest-reaching of the three vulnerabilities by version coverage. The fix ships in the same batch: 18.9.6, 18.10.4, and 18.11.1. The vulnerability was reported by security researcher pwnie via HackerOne (report #2915694).

The 15-Month Discovery-to-Patch Gap

CVE reservation in January 2025, public patch in April 2026. That's a 15-month window. This gap doesn't necessarily indicate slow response — CVE reservation triggers a coordinated disclosure process, not an immediate public announcement. GitLab bundles fixes into regular security release cycles, and the timeline suggests the vulnerability was identified, engineered through to a fix, and held for coordinated batch disclosure.

What this gap does mean for operations teams is that if this vulnerability was known to any threat actors before the public disclosure, it had a long exploitation window. Auditing logs for unusual activity on the discussions endpoint — high-volume requests with abnormal processing times, requests from accounts that don't normally interact with merge request discussions — is a worthwhile post-patch exercise, particularly for instances that were slow to update.

Comparative Analysis

CVEAttack SurfaceAffected FromCVE ReservedCVSS 3.1CWE
CVE-2026-1660Issue importv12.3Jan 20266.5 MediumCWE-770
CVE-2025-3922GraphQL APIv12.420256.5 MediumCWE-770
CVE-2025-0186Discussions endpointv10.6Jan 20256.5 MediumCWE-770

The uniform CVSS vector and CWE classification across three unrelated features point to a systemic gap rather than isolated bugs: GitLab's authenticated API surfaces historically lacked consistent resource budgeting. Each feature team implemented their endpoint independently, and in each case, the assumption that authentication implies reasonable usage went unchallenged. The April 2026 release closes these gaps simultaneously, suggesting a targeted internal audit identified the pattern.

The Developer Assumption That Creates CWE-770

Resource exhaustion vulnerabilities in authenticated systems almost always trace back to the same flawed reasoning: trusted users won't abuse the system. This reasoning leads to architectures where authentication gates are present but per-operation resource guardrails are absent. Adding cost analysis to every API endpoint is non-trivial — it adds complexity, requires understanding execution profiles, and complicates testing. So it gets deferred, and the exposure accumulates quietly.

The correct model is: authenticate first, then budget resources independently of identity. HTTP-level rate limiting helps but doesn't address within-request resource consumption. A single oversized GraphQL query or a single massive import job can exhaust server resources even when overall request rates look completely normal to a rate limiter counting requests per second.

Throttled vs. Unthrottled: How Resource Control Changes the Outcome

VULNERABLE — No ThrottlingAttackerfloodGitLabServerRAM exhausted503 — Service DownLegit UsersblockedAuthentication does not equal Resource BudgetPATCHED — Cost Analyzer ActiveAttackerLegit UserQuery CostAnalyzer429GitLabServer OKResources stableAuthenticate + Budget separately

The diagram illustrates the core difference. On the left, every authenticated request reaches the processing layer unchecked — resource consumption grows until the service fails and legitimate users are collateral damage. On the right, a cost analyzer evaluates each request before it reaches the execution layer, rejecting oversized operations with a 429 regardless of the requester's identity. Authentication controls access; cost analysis controls resource impact.

How to Patch Your Self-Managed GitLab Instance

Upgrading is the only complete remediation for all three CVEs. There are no configuration-only mitigations:

  1. Confirm your current version: sudo gitlab-rake gitlab:env:info or visit Admin Area → GitLab version.
  2. If on 12.3–18.9.5: upgrade to 18.9.6.
  3. If on 18.10.0–18.10.3: upgrade to 18.10.4.
  4. If on 18.11.0: upgrade to 18.11.1.
  5. For Omnibus installations: sudo apt-get install gitlab-ee=18.9.6-ee.0 (adjust edition and version as needed).
  6. After the upgrade, verify via the Admin Area and run sudo gitlab-ctl status to confirm all services are running cleanly.

As an interim measure while coordinating the upgrade, consider placing an additional NGINX or HAProxy layer in front of the GitLab API that enforces request body size limits and per-IP rate limiting on the /api/graphql, import, and discussions-related endpoints. This won't fully close the vulnerability but it narrows the viable attack window significantly.

Frequently Asked Questions

Do these vulnerabilities allow data theft or remote code execution?

No. All three CVEs are classified as availability-only attacks. The CVSS vector shows zero confidentiality (C:N) and zero integrity (I:N) impact. An attacker can degrade or halt the service but cannot read data or execute arbitrary code through these specific vulnerabilities.

Is GitLab.com affected?

No. GitLab's SaaS platform was updated to patched versions before the public disclosure on April 22, 2026. These vulnerabilities exclusively affect self-managed installations running unpatched versions.

Can the attack be triggered anonymously?

No. All three CVEs require a valid authenticated session (PR:L in CVSS terms — low privilege). Anonymous requests to the vulnerable endpoints are rejected before reaching the exploitable code paths.

We were slow to patch CVE-2025-0186 — should we audit our logs?

Yes. Given its January 2025 reservation date, this vulnerability had a long potential exposure window. Look for unusual volumes of requests to the discussions endpoint, issue import jobs with abnormal processing times, or GraphQL queries with disproportionately long execution durations. Correlate against accounts that don't normally use those features heavily.

Do these affect GitLab Runners or CI pipelines directly?

Indirectly. These vulnerabilities target the GitLab server layer — the API and application tier. Runners themselves are unaffected. However, since runners depend on the server's API to poll for jobs, report results, and communicate status, a DoS against the server will cause pipelines to stall, time out, or report failures unrelated to the actual code being built.

Conclusion

CVE-2026-1660, CVE-2025-3922, and CVE-2025-0186 make the same argument from three different angles: authentication is not a resource control boundary. Knowing who made a request does not constrain what that request is allowed to consume. GitLab's April 2026 security batch closes three distinct attack surfaces — issue imports, GraphQL queries, and discussion threads — that all shared this gap in a single coordinated release.

The fix is available, the upgrade path is documented, and the risk of inaction is concrete: full availability loss with only a valid login required. Update your self-managed instances. And if you're building your own APIs, audit your authenticated endpoints for unconstrained resource allocation — CWE-770 is consistently underestimated until something falls over at the worst possible moment.

References

Subscribe

Get the latest posts delivered right to your inbox.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Comments

No comments yet. Be the first to share your thoughts!

Subscribed!

Registered! A confirmation link has been sent to your email address. If you don't see it, please check your spam folder.

Error

An error occurred. Please try again.