Skip to content

Conversation

@bensheldon
Copy link

@bensheldon bensheldon commented Jun 8, 2022

Closes #1714.

I added additional behavior to the existing check_regex_dos.rb file. I thought it seemed like the correct location because it is checking for ReDoS, though it's arguably a bit different because it's checking methods on String rather than regex literals.

I also am not sure whether I should also validate that the object being passed to match/match? is a String; it seems like the expectation is that any user_input will be a string, but I'm not confident about that.

@bensheldon bensheldon changed the title 3.2Expand Regex DoS check to include String#match and #match? coercion Expand Regex DoS check to include String#match and #match? coercion Jun 8, 2022
@bensheldon
Copy link
Author

oops, sorry this got submitted in a half-written state. Cat on keyboard problems 😸

Brakeman.debug "Finding dynamic regexes"
calls = tracker.find_call :method => [:brakeman_regex_interp]
COERCES_STRING_TO_REGEX.each do |coercion_method|
calls.concat tracker.find_call(:method => [coercion_method]).select { |call| string?(call[:target]) }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could simplify this to

tracker.find_call(:methods => CEORCES_STRING_TO_REGEX).select { ... }

@bensheldon
Copy link
Author

@presidentbeef I updated the code based on your feedback. Thank you! 🙏🏻

I also made one behavior change: I added a method called string_or_modified_string? that recurses down the target to see if the initial call was a String. I added this because I found making a trivial modification like downcase would not trigger the check (e.g. "haystack".downcase.match(params[:unsafe])). I couldn't find an existing recursive method, but maybe I overlooked one.

@presidentbeef
Copy link
Owner

In real code, would we expect to see string literals like the test cases? 🤔

@bensheldon
Copy link
Author

In real code, would we expect to see string literals like the test cases? 🤔

This was the code we discovered (lightly anonymized):

result = @active_record_resource.a_hash_value
  .keys
  .select { |key| key.downcase.match?(unsafe_string_query) }
  .sort

I'd love advice for better ways to identify [String]#match?([String]).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Check: REDoS from match/match? coercing unsafe strings to regular expressions

2 participants