diff --git a/.rubocop.yml b/.rubocop.yml index 72a72528..a6cd330b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -12,6 +12,8 @@ Layout/SpaceAroundMethodCallOperator: Enabled: true Lint/DeprecatedOpenSSLConstant: Enabled: true +Lint/MixedRegexpCaptureTypes: + Enabled: true Lint/UriEscapeUnescape: Enabled: false Lint/RaiseException: @@ -28,7 +30,7 @@ Metrics/ClassLength: Exclude: - 'app/controllers/enumeration/cli_options.rb' Metrics/CyclomaticComplexity: - Max: 8 + Max: 10 Metrics/MethodLength: Max: 20 Exclude: @@ -50,5 +52,11 @@ Style/HashTransformValues: Style/NumericPredicate: Exclude: - 'app/controllers/vuln_api.rb' +Style/RedundantFetchBlock: + Enabled: true +Style/RedundantRegexpCharacterClass: + Enabled: true +Style/RedundantRegexpEscape: + Enabled: true Style/SlicingWithRange: Enabled: true diff --git a/app/controllers/password_attack.rb b/app/controllers/password_attack.rb index d970565b..a46e5cd7 100644 --- a/app/controllers/password_attack.rb +++ b/app/controllers/password_attack.rb @@ -82,7 +82,7 @@ module WPScan if xmlrpc&.enabled? && xmlrpc.available_methods.include?('wp.getUsersBlogs') && xmlrpc.method_call('wp.getUsersBlogs', [SecureRandom.hex[0, 6], SecureRandom.hex[0, 4]]) - .run.body !~ /XML\-RPC services are disabled/ + .run.body !~ /XML-RPC services are disabled/ true else diff --git a/app/finders/interesting_findings/mu_plugins.rb b/app/finders/interesting_findings/mu_plugins.rb index 01cc6e76..48be67f6 100644 --- a/app/finders/interesting_findings/mu_plugins.rb +++ b/app/finders/interesting_findings/mu_plugins.rb @@ -7,7 +7,7 @@ module WPScan class MuPlugins < CMSScanner::Finders::Finder # @return [ InterestingFinding ] def passive(_opts = {}) - pattern = %r{#{target.content_dir}/mu\-plugins/}i + pattern = %r{#{target.content_dir}/mu-plugins/}i target.in_scope_uris(target.homepage_res, '(//@href|//@src)[contains(., "mu-plugins")]') do |uri| next unless uri.path&.match?(pattern) diff --git a/app/finders/main_theme/css_style_in_homepage.rb b/app/finders/main_theme/css_style_in_homepage.rb index ed0eab7f..3b5ac501 100644 --- a/app/finders/main_theme/css_style_in_homepage.rb +++ b/app/finders/main_theme/css_style_in_homepage.rb @@ -21,7 +21,7 @@ module WPScan def passive_from_css_href(res, opts) target.in_scope_uris(res, '//link/@href[contains(., "style.css")]') do |uri| - next unless uri.path =~ %r{/themes/([^\/]+)/style.css\z}i + next unless uri.path =~ %r{/themes/([^/]+)/style.css\z}i return create_theme(Regexp.last_match[1], uri.to_s, opts) end @@ -33,7 +33,7 @@ module WPScan code = tag.text.to_s next if code.empty? - next unless code =~ %r{#{item_code_pattern('themes')}\\?/style\.css[^"'\( ]*}i + next unless code =~ %r{#{item_code_pattern('themes')}\\?/style\.css[^"'( ]*}i return create_theme(Regexp.last_match[1], Regexp.last_match[0].strip, opts) end diff --git a/app/finders/plugin_version/readme.rb b/app/finders/plugin_version/readme.rb index 82477dfb..fe63f5e8 100644 --- a/app/finders/plugin_version/readme.rb +++ b/app/finders/plugin_version/readme.rb @@ -48,7 +48,7 @@ module WPScan # # @return [ String, nil ] The version number detected from the stable tag def from_stable_tag(body) - return unless body =~ /\b(?:stable tag|version):\s*(?!trunk)([0-9a-z\.-]+)/i + return unless body =~ /\b(?:stable tag|version):\s*(?!trunk)([0-9a-z.-]+)/i number = Regexp.last_match[1] @@ -59,7 +59,7 @@ module WPScan # # @return [ String, nil ] The best version number detected from the changelog section def from_changelog_section(body) - extracted_versions = body.scan(%r{[=]+\s+(?:v(?:ersion)?\s*)?([0-9\.-]+)[ \ta-z0-9\(\)\.\-\/]*[=]+}i) + extracted_versions = body.scan(%r{=+\s+(?:v(?:ersion)?\s*)?([0-9.-]+)[ \ta-z0-9().\-/]*=+}i) return if extracted_versions.nil? || extracted_versions.empty? diff --git a/app/finders/theme_version/style.rb b/app/finders/theme_version/style.rb index 4362ac6c..85adf1d4 100644 --- a/app/finders/theme_version/style.rb +++ b/app/finders/theme_version/style.rb @@ -30,7 +30,7 @@ module WPScan # @return [ Version ] def style_version - return unless Browser.get(target.style_url).body =~ /Version:[\t ]*(?!trunk)([0-9a-z\.-]+)/i + return unless Browser.get(target.style_url).body =~ /Version:[\t ]*(?!trunk)([0-9a-z.-]+)/i Model::Version.new( Regexp.last_match[1], diff --git a/app/finders/users/rss_generator.rb b/app/finders/users/rss_generator.rb index d20391e7..dabf7579 100644 --- a/app/finders/users/rss_generator.rb +++ b/app/finders/users/rss_generator.rb @@ -13,7 +13,7 @@ module WPScan urls.each do |url| res = Browser.get_and_follow_location(url) - next unless res.code == 200 && res.body =~ //i + next unless res.code == 200 && res.body =~ //i potential_usernames = [] diff --git a/app/finders/users/yoast_seo_author_sitemap.rb b/app/finders/users/yoast_seo_author_sitemap.rb index 55023ffa..82f733dd 100644 --- a/app/finders/users/yoast_seo_author_sitemap.rb +++ b/app/finders/users/yoast_seo_author_sitemap.rb @@ -13,7 +13,7 @@ module WPScan found = [] Browser.get(sitemap_url).html.xpath('//url/loc').each do |user_tag| - username = user_tag.text.to_s[%r{/author/([^\/]+)/}, 1] + username = user_tag.text.to_s[%r{/author/([^/]+)/}, 1] next unless username && !username.strip.empty? diff --git a/app/finders/wp_items/urls_in_page.rb b/app/finders/wp_items/urls_in_page.rb index 849c553d..9056ddbf 100644 --- a/app/finders/wp_items/urls_in_page.rb +++ b/app/finders/wp_items/urls_in_page.rb @@ -55,7 +55,7 @@ module WPScan # # @return [ Regexp ] def item_code_pattern(type) - @item_code_pattern ||= %r{["'\( ]#{item_url_pattern(type)}([^\\\/\)"']+)}i + @item_code_pattern ||= %r{["'( ]#{item_url_pattern(type)}([^\\/)"']+)}i end # @param [ String ] type @@ -66,9 +66,9 @@ module WPScan item_url = type == 'plugins' ? target.plugins_url : target.content_url url = /#{item_url.gsub(/\A(?:https?)/i, 'https?').gsub('/', '\\\\\?\/')}/i - item_dir = %r{(?:#{url}|\\?\/#{item_dir.gsub('/', '\\\\\?\/')}\\?/)}i + item_dir = %r{(?:#{url}|\\?/#{item_dir.gsub('/', '\\\\\?\/')}\\?/)}i - type == 'plugins' ? item_dir : %r{#{item_dir}#{type}\\?\/}i + type == 'plugins' ? item_dir : %r{#{item_dir}#{type}\\?/}i end end end diff --git a/app/models/theme.rb b/app/models/theme.rb index b6a48ab3..e55bf9b7 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -45,7 +45,7 @@ module WPScan # @return [ Theme ] def parent_theme return unless template - return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i + return unless style_body =~ /^@import\surl\(["']?([^"')]+)["']?\);\s*$/i opts = detection_opts.merge( style_url: url(Regexp.last_match[1]), @@ -101,7 +101,7 @@ module WPScan # # @return [ String ] def parse_style_tag(body, tag) - value = body[/#{Regexp.escape(tag)}:[\t ]*([^\r\n\*]+)/i, 1] + value = body[/#{Regexp.escape(tag)}:[\t ]*([^\r\n*]+)/i, 1] value && !value.strip.empty? ? value.strip : nil end diff --git a/lib/wpscan/finders/dynamic_finder/version/config_parser.rb b/lib/wpscan/finders/dynamic_finder/version/config_parser.rb index 29e52daa..986515c6 100644 --- a/lib/wpscan/finders/dynamic_finder/version/config_parser.rb +++ b/lib/wpscan/finders/dynamic_finder/version/config_parser.rb @@ -11,7 +11,7 @@ module WPScan def self.child_class_constants @child_class_constants ||= super.merge( - PARSER: nil, KEY: nil, PATTERN: /(?\d+\.[\.\d]+)/, CONFIDENCE: 70 + PARSER: nil, KEY: nil, PATTERN: /(?\d+\.[.\d]+)/, CONFIDENCE: 70 ) end diff --git a/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb b/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb index 9aa0fc17..bf8cf532 100644 --- a/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +++ b/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb @@ -9,7 +9,7 @@ module WPScan # @return [ Hash ] def self.child_class_constants @child_class_constants ||= super().merge( - XPATH: nil, FILES: nil, PATTERN: /(?:v|ver|version)\=(?\d+\.[\.\d]+)/i, CONFIDENCE_PER_OCCURENCE: 10 + XPATH: nil, FILES: nil, PATTERN: /(?:v|ver|version)=(?\d+\.[.\d]+)/i, CONFIDENCE_PER_OCCURENCE: 10 ) end diff --git a/lib/wpscan/finders/dynamic_finder/version/xpath.rb b/lib/wpscan/finders/dynamic_finder/version/xpath.rb index 0a9f09eb..b5203e3e 100644 --- a/lib/wpscan/finders/dynamic_finder/version/xpath.rb +++ b/lib/wpscan/finders/dynamic_finder/version/xpath.rb @@ -9,7 +9,7 @@ module WPScan # @return [ Hash ] def self.child_class_constants @child_class_constants ||= super().merge( - XPATH: nil, PATTERN: /\A(?\d+\.[\.\d]+)/, CONFIDENCE: 60 + XPATH: nil, PATTERN: /\A(?\d+\.[.\d]+)/, CONFIDENCE: 60 ) end diff --git a/lib/wpscan/finders/dynamic_finder/wp_version.rb b/lib/wpscan/finders/dynamic_finder/wp_version.rb index c974f0a7..75cc0f90 100644 --- a/lib/wpscan/finders/dynamic_finder/wp_version.rb +++ b/lib/wpscan/finders/dynamic_finder/wp_version.rb @@ -33,7 +33,7 @@ module WPScan # @return [ Hash ] def self.child_class_constants - @child_class_constants ||= super().merge(PATTERN: /ver\=(?\d+\.[\.\d]+)/i) + @child_class_constants ||= super().merge(PATTERN: /ver=(?\d+\.[.\d]+)/i) end end diff --git a/lib/wpscan/helper.rb b/lib/wpscan/helper.rb index c335ade2..9eaa9ac5 100644 --- a/lib/wpscan/helper.rb +++ b/lib/wpscan/helper.rb @@ -13,7 +13,7 @@ end # # @return [ Symbol ] def classify_slug(slug) - classified = slug.to_s.gsub(/[^a-z\d\-]/i, '-').gsub(/\-{1,}/, '_').camelize.to_s + classified = slug.to_s.gsub(/[^a-z\d\-]/i, '-').gsub(/-{1,}/, '_').camelize.to_s classified = "D_#{classified}" if /\d/.match?(classified[0]) classified.to_sym diff --git a/lib/wpscan/target/platform/wordpress.rb b/lib/wpscan/target/platform/wordpress.rb index b37c2e4e..962c0ccf 100644 --- a/lib/wpscan/target/platform/wordpress.rb +++ b/lib/wpscan/target/platform/wordpress.rb @@ -11,9 +11,9 @@ module WPScan module WordPress include CMSScanner::Target::Platform::PHP - WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze - WP_JSON_OEMBED_PATTERN = %r{/wp\-json/oembed/}i.freeze - WP_ADMIN_AJAX_PATTERN = %r{\\?/wp\-admin\\?/admin\-ajax\.php}i.freeze + WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu-)?plugins|uploads))|wp-includes)/}i.freeze + WP_JSON_OEMBED_PATTERN = %r{/wp-json/oembed/}i.freeze + WP_ADMIN_AJAX_PATTERN = %r{\\?/wp-admin\\?/admin-ajax\.php}i.freeze # These methods are used in the associated interesting_findings finders # to keep the boolean state of the finding rather than re-check the whole thing again @@ -147,7 +147,7 @@ module WPScan res = Browser.get_and_follow_location(@login_url) - @login_url = res.effective_url if res.effective_url =~ /wp\-login\.php\z/i && in_scope?(res.effective_url) + @login_url = res.effective_url if res.effective_url =~ /wp-login\.php\z/i && in_scope?(res.effective_url) @login_url end diff --git a/lib/wpscan/target/platform/wordpress/custom_directories.rb b/lib/wpscan/target/platform/wordpress/custom_directories.rb index 938a8e36..2b901f91 100644 --- a/lib/wpscan/target/platform/wordpress/custom_directories.rb +++ b/lib/wpscan/target/platform/wordpress/custom_directories.rb @@ -104,7 +104,7 @@ module WPScan return @sub_dir unless @sub_dir.nil? # url_pattern is from CMSScanner::Target - pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i + pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp-includes/)}i xpath = '(//@src|//@href|//@data-src)[contains(., "xmlrpc.php") or contains(., "wp-includes/")]' [homepage_res, error_404_res].each do |page_res| @@ -124,9 +124,9 @@ module WPScan def url(path = nil) return @uri.to_s unless path - if %r{wp\-content/plugins}i.match?(path) + if %r{wp-content/plugins}i.match?(path) path = +path.gsub('wp-content/plugins', plugins_dir) - elsif /wp\-content/i.match?(path) + elsif /wp-content/i.match?(path) path = +path.gsub('wp-content', content_dir) elsif path[0] != '/' && sub_dir path = "#{sub_dir}/#{path}" diff --git a/spec/lib/finders/dynamic_finder/version/comment_spec.rb b/spec/lib/finders/dynamic_finder/version/comment_spec.rb index 5c62ad19..a73252ce 100644 --- a/spec/lib/finders/dynamic_finder/version/comment_spec.rb +++ b/spec/lib/finders/dynamic_finder/version/comment_spec.rb @@ -13,7 +13,7 @@ describe WPScan::Finders::DynamicFinder::Version::Comment do let(:finder_module) { WPScan::Finders::Version::Rspec } let(:finder_class) { WPScan::Finders::Version::Rspec::Comment } - let(:finder_config) { { 'pattern' => /some version: (?[\d\.]+)/i } } + let(:finder_config) { { 'pattern' => /some version: (?[\d.]+)/i } } let(:default) { { 'xpath' => '//comment()', 'confidence' => 60 } } before { described_class.create_child_class(finder_module, :Comment, finder_config) } diff --git a/spec/lib/finders/dynamic_finder/version/config_parser_spec.rb b/spec/lib/finders/dynamic_finder/version/config_parser_spec.rb index 777ba40b..ea99bf21 100644 --- a/spec/lib/finders/dynamic_finder/version/config_parser_spec.rb +++ b/spec/lib/finders/dynamic_finder/version/config_parser_spec.rb @@ -14,7 +14,7 @@ describe WPScan::Finders::DynamicFinder::Version::ConfigParser do let(:finder_module) { WPScan::Finders::Version::Rspec } let(:finder_class) { WPScan::Finders::Version::Rspec::ConfigParser } let(:finder_config) { { 'key' => 'some-key', 'path' => 'file.json' } } - let(:default) { { 'pattern' => /(?\d+\.[\.\d]+)/, 'confidence' => 70 } } + let(:default) { { 'pattern' => /(?\d+\.[.\d]+)/, 'confidence' => 70 } } before { described_class.create_child_class(finder_module, :ConfigParser, finder_config) } after { finder_module.send(:remove_const, :ConfigParser) } diff --git a/spec/lib/finders/dynamic_finder/version/header_pattern_spec.rb b/spec/lib/finders/dynamic_finder/version/header_pattern_spec.rb index af7ee206..f639a2f6 100644 --- a/spec/lib/finders/dynamic_finder/version/header_pattern_spec.rb +++ b/spec/lib/finders/dynamic_finder/version/header_pattern_spec.rb @@ -60,7 +60,7 @@ describe WPScan::Finders::DynamicFinder::Version::HeaderPattern do end context 'when PATTERN' do - let(:finder_config) { super().merge('pattern' => /Version: (?[\d\.]+)/i) } + let(:finder_config) { super().merge('pattern' => /Version: (?[\d.]+)/i) } it 'contains the expected constants' do expect(finder_class::HEADER).to eql finder_config['header'] diff --git a/spec/lib/finders/dynamic_finder/version/javascript_var_spec.rb b/spec/lib/finders/dynamic_finder/version/javascript_var_spec.rb index 4ea1ae49..ffe70c89 100644 --- a/spec/lib/finders/dynamic_finder/version/javascript_var_spec.rb +++ b/spec/lib/finders/dynamic_finder/version/javascript_var_spec.rb @@ -13,7 +13,7 @@ describe WPScan::Finders::DynamicFinder::Version::JavascriptVar do let(:finder_module) { WPScan::Finders::Version::Rspec } let(:finder_class) { WPScan::Finders::Version::Rspec::JavascriptVar } - let(:finder_config) { { 'pattern' => /some version: (?[\d\.]+)/i } } + let(:finder_config) { { 'pattern' => /some version: (?[\d.]+)/i } } let(:default) { { 'xpath' => '//script[not(@src)]', 'confidence' => 60 } } before { described_class.create_child_class(finder_module, :JavascriptVar, finder_config) } diff --git a/spec/lib/finders/dynamic_finder/version/query_parameter_spec.rb b/spec/lib/finders/dynamic_finder/version/query_parameter_spec.rb index 832fad2a..2b6ec657 100644 --- a/spec/lib/finders/dynamic_finder/version/query_parameter_spec.rb +++ b/spec/lib/finders/dynamic_finder/version/query_parameter_spec.rb @@ -14,7 +14,7 @@ describe WPScan::Finders::DynamicFinder::Version::QueryParameter do let(:finder_module) { WPScan::Finders::Version::Rspec } let(:finder_class) { WPScan::Finders::Version::Rspec::QueryParameter } let(:finder_config) { { 'files' => %w[f1 f2] } } - let(:default) { { 'pattern' => /(?:v|ver|version)\=(?\d+\.[\.\d]+)/i, 'confidence_per_occurence' => 10 } } + let(:default) { { 'pattern' => /(?:v|ver|version)=(?\d+\.[.\d]+)/i, 'confidence_per_occurence' => 10 } } before { described_class.create_child_class(finder_module, :QueryParameter, finder_config) } after { finder_module.send(:remove_const, :QueryParameter) } diff --git a/spec/lib/finders/dynamic_finder/version/xpath_spec.rb b/spec/lib/finders/dynamic_finder/version/xpath_spec.rb index e458548e..91d198ae 100644 --- a/spec/lib/finders/dynamic_finder/version/xpath_spec.rb +++ b/spec/lib/finders/dynamic_finder/version/xpath_spec.rb @@ -14,7 +14,7 @@ describe WPScan::Finders::DynamicFinder::Version::Xpath do let(:finder_module) { WPScan::Finders::Version::Rspec } let(:finder_class) { WPScan::Finders::Version::Rspec::Xpath } let(:finder_config) { { 'xpath' => "//div/h3[@class='version-number']" } } - let(:default) { { 'pattern' => /\A(?\d+\.[\.\d]+)/, 'confidence' => 60 } } + let(:default) { { 'pattern' => /\A(?\d+\.[.\d]+)/, 'confidence' => 60 } } before { described_class.create_child_class(finder_module, :Xpath, finder_config) } after { finder_module.send(:remove_const, :Xpath) } @@ -60,7 +60,7 @@ describe WPScan::Finders::DynamicFinder::Version::Xpath do end context 'when PATTERN' do - let(:finder_config) { super().merge('pattern' => /Version: (?[\d\.]+)/i) } + let(:finder_config) { super().merge('pattern' => /Version: (?[\d.]+)/i) } it 'contains the expected constants' do expect(finder_class::XPATH).to eql finder_config['xpath'] diff --git a/wpscan.gemspec b/wpscan.gemspec index 6d461a8f..27253153 100644 --- a/wpscan.gemspec +++ b/wpscan.gemspec @@ -28,7 +28,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'rake', '~> 13.0' s.add_development_dependency 'rspec', '~> 3.9.0' s.add_development_dependency 'rspec-its', '~> 1.3.0' - s.add_development_dependency 'rubocop', '~> 0.85.0' + s.add_development_dependency 'rubocop', '~> 0.86.0' s.add_development_dependency 'rubocop-performance', '~> 1.6.0' s.add_development_dependency 'simplecov', '~> 0.18.2' s.add_development_dependency 'simplecov-lcov', '~> 0.8.0'