class CMSScanner::Browser

Singleton used to perform HTTP/HTTPS request to the target

Options available in the Browser

Constants

OPTIONS

Public Class Methods

instance(parsed_options = {}) click to toggle source

@param [ Hash ] parsed_options

@return [ Browser ] The instance

# File lib/cms_scanner/browser.rb, line 25
def self.instance(parsed_options = {})
  @@instance ||= new(parsed_options)
end
reset() click to toggle source
# File lib/cms_scanner/browser.rb, line 29
def self.reset
  @@instance = nil
end

Private Class Methods

new(parsed_options = {}) click to toggle source

@param [ Hash ] parsed_options

@return [ Void ]

# File lib/cms_scanner/browser.rb, line 14
def initialize(parsed_options = {})
  self.throttle = 0

  load_options(parsed_options.dup)
end

Public Instance Methods

default_connect_request_params() click to toggle source

@return [ Hash ] The request params used to connect tothe target as well as potential other systems such as API

# File lib/cms_scanner/browser.rb, line 42
def default_connect_request_params
  params = {}

  if disable_tls_checks
    # See http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
    params[:ssl_verifypeer] = false
    params[:ssl_verifyhost] = 0
    # TLSv1.0 and plus, allows to use a protocol potentially lower than the OS default
    params[:sslversion] = :tlsv1
  end

  {
    connecttimeout: :connect_timeout, cache_ttl: :cache_ttl,
    proxy: :proxy, timeout: :request_timeout
  }.each do |typhoeus_opt, browser_opt|
    attr_value = public_send(browser_opt)
    params[typhoeus_opt] = attr_value unless attr_value.nil?
  end

  params
end
default_request_params() click to toggle source

@return [ Hash ] The params are not cached (using @params ||= for example), so that they are set accordingly if updated by a controller/other piece of code

# File lib/cms_scanner/browser.rb, line 67
def default_request_params
  params = default_connect_request_params.merge(
    headers: { 'User-Agent' => user_agent, 'Referer' => url }.merge(headers || {}),
    accept_encoding: 'gzip, deflate',
    method: :get
  )

  { cookiejar: :cookie_jar, cookiefile: :cookie_jar, cookie: :cookie_string }.each do |typhoeus_opt, browser_opt|
    attr_value = public_send(browser_opt)
    params[typhoeus_opt] = attr_value unless attr_value.nil?
  end

  params[:proxyuserpwd] = "#{proxy_auth[:username]}:#{proxy_auth[:password]}" if proxy_auth
  params[:userpwd] = "#{http_auth[:username]}:#{http_auth[:password]}" if http_auth

  params[:headers]['Host'] = vhost if vhost

  params
end
default_user_agent() click to toggle source

@return [ String ]

# File lib/cms_scanner/browser/options.rb, line 29
def default_user_agent
  "#{NS} v#{NS::VERSION}"
end
forge_request(url, params = {}) click to toggle source

@param [ String ] url @param [ Hash ] params

@return [ Typhoeus::Request ]

# File lib/cms_scanner/browser.rb, line 37
def forge_request(url, params = {})
  Typhoeus::Request.new(url, request_params(params))
end
hydra() click to toggle source

@return [ Typhoeus::Hydra ]

# File lib/cms_scanner/browser/options.rb, line 34
def hydra
  @hydra ||= Typhoeus::Hydra.new(max_concurrency: max_threads || 1)
end
load_options(options = {}) click to toggle source

@param [ Hash ] options

# File lib/cms_scanner/browser/options.rb, line 39
def load_options(options = {})
  OPTIONS.each do |sym|
    send("#{sym}=", options[sym]) if options.key?(sym)
  end
end
max_threads=(number) click to toggle source

Set the threads attribute and update hydra accordinly If the throttle attribute is > 0, max_threads will be forced to 1

@param [ Integer ] number

# File lib/cms_scanner/browser/options.rb, line 49
def max_threads=(number)
  @max_threads = number.to_i.positive? && throttle.zero? ? number.to_i : 1

  hydra.max_concurrency = @max_threads
end
request_params(params = {}) click to toggle source

@param [ Hash ] params

@return [ Hash ]

# File lib/cms_scanner/browser.rb, line 90
def request_params(params = {})
  default_request_params.merge(params) do |key, oldval, newval|
    key == :headers ? oldval.merge(newval) : newval
  end
end
throttle=(value) click to toggle source

@param [ value ] The throttle time in milliseconds

if value > 0, the max_threads will be set to 1

# File lib/cms_scanner/browser/options.rb, line 80
def throttle=(value)
  @throttle = value.to_i.abs / 1000.0

  self.max_threads = 1 if @throttle.positive?
end
trottle!() click to toggle source
# File lib/cms_scanner/browser/options.rb, line 86
def trottle!
  sleep(throttle) if throttle.positive?
end
user_agent() click to toggle source

@return [ String ] The user agent

# File lib/cms_scanner/browser/options.rb, line 56
def user_agent
  @user_agent ||= random_user_agent ? user_agents.sample : default_user_agent
end
user_agents() click to toggle source

@return [ Array<String> ]

# File lib/cms_scanner/browser/options.rb, line 61
def user_agents
  return @user_agents if @user_agents

  @user_agents = []

  # The user_agents_list is managed by the CLI options, with the default being
  # APP_DIR/user_agents.txt
  File.open(user_agents_list).each do |line|
    next if line == "\n" || line[0, 1] == '#'

    @user_agents << line.chomp
  end

  @user_agents
end