class Arachni::Options
Provides access to all of {Arachni}‘s runtime options.
To make management of options for different subsystems easier, some options are {OptionGroups grouped together}.
{OptionGroups Option groups} are initialized and added as attribute readers to this class dynamically. Their attribute readers are named after the group’s filename and can be accessed, like so:
Arachni::Options.scope.page_limit = 10
@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com> @see OptionGroups
Attributes
@return [Array<String, Symbol>]
Checks to load, by name.
@see Checks
@see Check::Base
@see Check::Manager
@return [Bool]
Disable platform fingeprinting.
@see Platform::Fingerprinter
@see Platform::Fingerprinters
@see Platform::List
@see Platform::Manager
@return [Arachni::URI]
@return [Array<Symbol>]
Platforms to use instead of (or in addition to, depending on the {#no_fingerprinting option}) fingerprinting.
@see Platform
@see Platform::List
@see Platform::Manager
@return [Hash{<String, Symbol> => Hash{String => String}}]
Plugins to load, by name, as keys and their options as values.
@see Plugins
@see Plugin::Base
@see Plugin::Manager
@return [Integer]
Amount of child {RPC::Server::Instance}s to spawn when performing multi-{RPC::Server::Instance} scans.
@see UI::CLI::RPC::Instance#scan
@return [String]
The URL to audit.
Public Class Methods
@return [Hash<Symbol,OptionGroup>]
{OptionGroups Option group} classes by name.
# File lib/arachni/options.rb, line 73 def group_classes @group_classes ||= {} end
# File lib/arachni/options.rb, line 55 def method_missing( sym, *args, &block ) if instance.respond_to?( sym ) instance.send( sym, *args, &block ) else super( sym, *args, &block ) end end
# File lib/arachni/options.rb, line 150 def initialize reset end
Should be called by {OptionGroup.inherited}. @private
# File lib/arachni/options.rb, line 79 def register_group( group ) name = Utilities.caller_name # Prepare an attribute reader for this group... attr_reader name # ... and initialize it. instance_variable_set "@#{name}".to_sym, group.new group_classes[name.to_sym] = group end
# File lib/arachni/options.rb, line 63 def respond_to?( *args ) super || instance.respond_to?( *args ) end
Public Instance Methods
Disables platform fingerprinting.
# File lib/arachni/options.rb, line 185 def do_not_fingerprint self.no_fingerprinting = true end
Enables platform fingerprinting.
# File lib/arachni/options.rb, line 190 def fingerprint self.no_fingerprinting = false end
@return [Bool]
`true` if platform fingerprinting is enabled, `false` otherwise.
# File lib/arachni/options.rb, line 196 def fingerprint? !@no_fingerprinting end
@param [Hash] hash
Hash to convert into {#to_rpc_data} format.
@return [Hash]
`hash` in {#to_rpc_data} format.
# File lib/arachni/options.rb, line 391 def hash_to_rpc_data( hash ) self.class.allocate.reset.update( hash ).to_rpc_data end
# File lib/arachni/options.rb, line 395 def hash_to_save_data( hash ) self.class.allocate.reset.update( hash ).to_save_data end
Loads a file created by {#save}.
@param [String] filepath
Path to the file created by {#save}.
@return [Arachni::Options]
# File lib/arachni/options.rb, line 331 def load( filepath ) update( YAML.load_file( filepath ) ) end
Restores everything to their default values.
@return [Options] ‘self`
# File lib/arachni/options.rb, line 157 def reset # nil everything out. instance_variables.each { |var| instance_variable_set( var.to_s, nil ) } # Set fresh option groups. group_classes.each do |name, klass| instance_variable_set "@#{name}".to_sym, klass.new end @checks = [] @platforms = [] @plugins = {} @spawns = 0 @no_fingerprinting = false @authorized_by = nil self end
@param [Hash] hash
Hash to convert into {#to_hash} format.
@return [Hash]
`hash` in {#to_hash} format.
# File lib/arachni/options.rb, line 382 def rpc_data_to_hash( hash ) self.class.allocate.reset.update( hash ).to_hash end
@param [String] file
Saves `self` to `file` using YAML.
# File lib/arachni/options.rb, line 314 def save( file ) File.open( file, 'w' ) do |f| f.write to_save_data f.path end end
@param [Integer] spawns
@see spawns
# File lib/arachni/options.rb, line 180 def spawns=( spawns ) @spawns = spawns.to_i end
@return [Hash]
`self` converted to a Hash.
# File lib/arachni/options.rb, line 360 def to_hash hash = {} instance_variables.each do |var| val = instance_variable_get( var ) next if (var = normalize_name( var )) == :instance hash[var] = (val.is_a? OptionGroup) ? val.to_h : val end hash.delete( :url ) if !hash[:url] hash.delete( :parsed_url ) hash.delete(:paths) hash.deep_clone end
@return [Hash]
`self` converted to a Hash suitable for RPC transmission.
# File lib/arachni/options.rb, line 337 def to_rpc_data ignore = Set.new([:instance, :rpc, :dispatcher, :paths, :spawns, :snapshot, :output]) hash = {} instance_variables.each do |var| val = instance_variable_get( var ) var = normalize_name( var ) next if ignore.include?( var ) hash[var.to_s] = (val.is_a? OptionGroup) ? val.to_rpc_data : val end hash = hash.deep_clone hash.delete( 'url' ) if !hash['url'] hash.delete( 'parsed_url' ) hash end
# File lib/arachni/options.rb, line 321 def to_save_data to_rpc_data.to_yaml end
Configures options via a Hash
object.
@example Configuring direct and {OptionGroups} attributes.
{ # Direct Options#url attribute. url: 'http://test.com/', # Options#audit attribute pointing to an OptionGroups::Audit instance. audit: { # Works due to the OptionGroups::Audit#elements= helper method. elements: [ :links, :forms, :cookies ] }, # Direct Options#checks attribute. checks: [ :xss, 'sql_injection*' ], # Options#scope attribute pointing to an OptionGroups::Scope instance. scope: { # OptionGroups::Scope#page_limit page_limit: 10, # OptionGroups::Scope#directory_depth_limit directory_depth_limit: 3 }, # Options#http attribute pointing to an OptionGroups::HTTP instance. http: { # OptionGroups::HTTP#request_concurrency request_concurrency: 25, # OptionGroups::HTTP#request_timeout request_timeout: 10_000 } }
@param [Hash] options
If the key refers to a class attribute, the attribute will be assigned the given value, if it refers to one of the {OptionGroups} the value should be a hash with data to update that {OptionGroup group} using {OptionGroup#update}.
@return [Options]
@see OptionGroups
# File lib/arachni/options.rb, line 287 def update( options ) options.each do |k, v| k = k.to_sym if group_classes.include? k send( k ).update v else send( "#{k.to_s}=", v ) end end self end
Normalizes and sets ‘url` as the target URL.
@param [String] url
Absolute URL of the targeted web app.
@return [String]
Normalized `url`
@raise [Error::InvalidURL]
If the given `url` is not valid.
# File lib/arachni/options.rb, line 210 def url=( url ) return @url = nil if !url parsed = Arachni::URI( url.to_s ) if parsed.to_s.empty? || !parsed.absolute? fail Error::InvalidURL, 'Invalid URL argument, please provide a full absolute URL and try again.' # PhantomJS won't proxy localhost. elsif parsed.host == 'localhost' || parsed.host.start_with?( '127.' ) fail Error::ReservedHostname, "Loopback interfaces (like #{parsed.host}) are not supported," << ' please use a different IP address or hostname.' else if scope.https_only? && parsed.scheme != 'https' fail Error::InvalidURL, "Invalid URL argument, the 'https-only' option requires"+ ' an HTTPS URL.' elsif !%w(http https).include?( parsed.scheme ) fail Error::InvalidURL, 'Invalid URL scheme, please provide an HTTP or HTTPS URL and try again.' end end @parsed_url = parsed @url = parsed.to_s end
@return [Hash]
Hash of errors with the name of the invalid options/groups as the keys.
# File lib/arachni/options.rb, line 303 def validate errors = {} group_classes.keys.each do |name| next if (group_errors = send(name).validate).empty? errors[name] = group_errors end errors end
Private Instance Methods
# File lib/arachni/options.rb, line 401 def group_classes self.class.group_classes end
# File lib/arachni/options.rb, line 405 def normalize_name( name ) name.to_s.gsub( '@', '' ).to_sym end