Skip to content

Truncate large user agents when detecting browser to avoid 500#6036

Merged
mitchellhenke merged 2 commits intomainfrom
mitchellhenke/browser-user-agent-too-big
Mar 7, 2022
Merged

Truncate large user agents when detecting browser to avoid 500#6036
mitchellhenke merged 2 commits intomainfrom
mitchellhenke/browser-user-agent-too-big

Conversation

@mitchellhenke
Copy link
Contributor

Copy link
Contributor

@zachmargolis zachmargolis left a comment

Choose a reason for hiding this comment

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

LGTM, yikes what a weird bug.... but I guess it's probably guarding against some sort of resource abuse

Copy link
Contributor

Choose a reason for hiding this comment

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

The gem README in the gem is bytes not characters, so I think this method is more appropriate:

Suggested change
@cache.getset(user_agent) { Browser.new(user_agent[0..2046]) }
@cache.getset(user_agent) { Browser.new(user_agent.byteslice(0..2046)) }

https://ruby-doc.org/core-3.1.1/String.html#method-i-byteslice

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great catch, that made me think of another fun edge case!

Browser.new("abc👏🏼".byteslice(0..3))
# => ArgumentError: invalid byte sequence in UTF-8
# => from /Users/mitchellehenke/projects/identity-idp/.gem/ruby/3.0.3/gems/browser-5.3.1/lib/browser/blackberry.rb:20:in `match?'

It looks like the most complete is to truncate with the multibyte characters class from Rails, which will avoid splitting in the middle of a character.

@cache.getset(user_agent) { Browser.new(user_agent.mb_chars.limit(2047)) }

Copy link
Contributor

Choose a reason for hiding this comment

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

ooo yes good thought

@mitchellhenke mitchellhenke force-pushed the mitchellhenke/browser-user-agent-too-big branch 2 times, most recently from e5e650f to 9461498 Compare March 7, 2022 17:41
Mitchell Henke and others added 2 commits March 7, 2022 11:52
changelog: Bug Fix, Logging, Fix 500 when parsing browser user-agent that is too long
Co-authored-by: Zach Margolis <zachmargolis@users.noreply.github.com>
@mitchellhenke mitchellhenke force-pushed the mitchellhenke/browser-user-agent-too-big branch from 9461498 to 8aae8e2 Compare March 7, 2022 17:52
@mitchellhenke mitchellhenke merged commit 7c054d2 into main Mar 7, 2022
@mitchellhenke mitchellhenke deleted the mitchellhenke/browser-user-agent-too-big branch March 7, 2022 18:07
def self.parse(user_agent)
@cache.getset(user_agent) { Browser.new(user_agent) }
return Browser.new(nil) if user_agent.nil?
@cache.getset(user_agent) { Browser.new(user_agent.mb_chars.limit(2047).to_s) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we have used the constant value, to avoid a magic number?

Suggested change
@cache.getset(user_agent) { Browser.new(user_agent.mb_chars.limit(2047).to_s) }
@cache.getset(user_agent) { Browser.new(user_agent.mb_chars.limit(Browser.user_agent_size_limit - 1).to_s) }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, absolutely #6056

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.

3 participants