Zero Complexity Multiplier Bypasses Complexity Limit, Allowing Unauthenticated DoS

⚠️ 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 #3228134 by foxribeye on 2025-06-28, assigned to @katwu:

Report | Attachments | How To Reproduce

Report

The bug is that the condition [args[:iid], args[:iids]].any? is always true (especially when you pass IDs), so complexity_multiplier always returns 0.

This means as soon as you pass an iid, complexity_multiplier returns 0, so the query is treated as having zero cost, completely bypassing the complexly limit. So, an unauthenticated attacker can use many ids, this bypasses the max complexity limit of 200, allows for DoS.

The bug is located here:
app/graphql/resolvers/base_resolver.rb

def self.complexity_multiplier(args)  
  [args[:iid], args[:iids]].any? ? 0 : 0.01  
end  
Steps to reproduce

(self-hosted test)

  1. Save this script: dos.py
  2. Then run script in shell like this:

for i in {1..12}; do python dos.py -u http://localhost:8080 -n 250000 -c 4 & sleep 5 done

(This sends 4 parallel requests every 5 seconds, repeated 12 times, peaking at only 4 rps. Each request uses 250000 ids)

  1. On your shell where instance is, run htop and you’ll see the puma workers saturating cpu. Navigate to instance on browser notice gitlab instance becomes unresponsive.

Poc:
dos.mp4

Impact

Requests from unauthenticated users can saturate cpu resources and render the instance unresponsive.

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section: