Skip to content

An RDoc file containing a specially crafted regex can crash puma

HackerOne report #1415071 by vakzz on 2021-12-02, assigned to @dcouture:

Report | Attachments | How To Reproduce

Report

Summary

There is a stack-buffer-overflow in ruby still affecting ruby 2.7.x that can cause a segmentation fault and crash when compiling certain regexes.

Normally there would be no way for a user to specify their own regex to be compiled, but when rendering rdoc files there is a check to see if a block of text is valid ruby:

https://github.com/ruby/rdoc/blob/master/lib/rdoc/markup/to_html.rb#L427

  ##  
  # Returns true if text is valid ruby syntax

  def parseable? text  
    verbose, $VERBOSE = $VERBOSE, nil  
    eval("BEGIN {return true}\n#{text}")  
  rescue SyntaxError  
    false  
  ensure  
    $VERBOSE = verbose  
  end  

This will never execute any code except for returning true due to how BEGIN works (I'm pretty sure anyway) but will run it through the ruby parser to generate an ast. Since regexes are compiled during this stage, it's possible to trigger the stack overflow using the following readme.rdoc:

code:  
  /(())(?<X>)((?(2147483647)))/  

I might me possible to exploit the buffer overflow instead of just causing a crash, but if it is possible it would be quite difficult due to not having a leak for aslr and single shot.

Steps to reproduce
  1. Create a new project
  2. Create a new file aaa.rdocwith the following contents:
code:  
  /(())(?<X>)((?(2147483647)))/  
  1. Commit and try to view the file
  2. There will be an error loading the viewer, the request for the rich version will return 502 as puma has crashed
Impact

A malicious rdoc can cause puma to crash when it's rendered. A user could constantly request the url, constantly crashing all of the puma processes and denying access to the gitlab instance. For example running the following ffuf with a rate of just 1 request per second is enough to bring down my vm and prevent any legitimate requests:

ffuf -u 'http://localhost:8888/root/crash/-/blob/main/aaa.rdoc?format=json&viewer=rich&FUZZ' -w /usr/share/dict/words -rate 1 -t 5  
Examples

POC repo - https://gitlab.com/vakzz-h1/rdoc-crash/
Crashing example: https://gitlab.com/vakzz-h1/rdoc-crash/-/blob/main/aaa.rdoc?format=json&viewer=rich

What is the current bug behavior?

Ruby crashes when trying to parse a specific regex

What is the expected correct behavior?

Ruby shouldn't crash when parsing regexes, and rdoc probably shouldn't eval code even with the BEGIN guard

Relevant logs and/or screenshots

regex-crash.log

Output of checks

This bug happens on GitLab.com

Impact

A malicious rdoc can cause puma to crash when it's rendered. A user could constantly request the url, constantly crashing all of the puma processes and denying access to the gitlab instance. For example running the following ffuf with a rate of just 1 request per second is enough to bring down my vm and prevent any legitimate requests:

ffuf -u 'http://localhost:8888/root/crash/-/blob/main/aaa.rdoc?format=json&viewer=rich&FUZZ' -w /usr/share/dict/words -rate 1 -t 5  

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section: