diff --git a/app/models/project.rb b/app/models/project.rb index 15465d9b3567b44acab0b8d1df77af5eaf0327fc..f273cbda82475715b44717970edbc9f1c4ab6c4c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -530,6 +530,7 @@ class Project < ActiveRecord::Base def reference_pattern %r{ + (?#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})\/)? (?#{Gitlab::PathRegex::PROJECT_PATH_FORMAT_REGEX}) }x diff --git a/changelogs/unreleased/security-fix-regex-dos.yml b/changelogs/unreleased/security-fix-regex-dos.yml new file mode 100644 index 0000000000000000000000000000000000000000..b08566d2f1525301406ebd61414336bff3d24cfe --- /dev/null +++ b/changelogs/unreleased/security-fix-regex-dos.yml @@ -0,0 +1,5 @@ +--- +title: Fix slow regex in project reference pattern +merge_request: +author: +type: security diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb index fa68dead80b43e19b405ea2185f1c642b384db27..3c888be071018eac4689c5fd1706ec5acb7b3409 100644 --- a/lib/gitlab/path_regex.rb +++ b/lib/gitlab/path_regex.rb @@ -125,7 +125,8 @@ module Gitlab # allow non-regex validations, etc), `NAMESPACE_FORMAT_REGEX_JS` serves as a Javascript-compatible version of # `NAMESPACE_FORMAT_REGEX`, with the negative lookbehind assertion removed. This means that the client-side validation # will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation. - PATH_REGEX_STR = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*'.freeze + PATH_START_CHAR = '[a-zA-Z0-9_\.]'.freeze + PATH_REGEX_STR = PATH_START_CHAR + '[a-zA-Z0-9_\-\.]*'.freeze NAMESPACE_FORMAT_REGEX_JS = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze NO_SUFFIX_REGEX = /(? character' do doc = reference_filter("Hey #{reference}foo") expect(doc.css('a').first.attr('href')).to eq urls.project_url(subject)