Class: Arachni::Issue
- Defined in:
- lib/arachni/issue.rb,
lib/arachni/issue/severity.rb,
lib/arachni/issue/severity/base.rb
Overview
Represents a detected issue.
Defined Under Namespace
Modules: Severity
Constant Summary collapse
- VARIATION_ATTRIBUTES =
Attributes removed from a parent issue (i.e. an issues with variations) and solely populating variations.
Set.new([ :@page, :@referring_page, :@proof, :@signature, :@remarks, :@trusted ])
Instance Attribute Summary collapse
-
#check ⇒ Hash
Information about the check that logged the issue.
-
#cwe ⇒ String
The CWE ID number of the issue.
-
#description ⇒ String
Brief description.
-
#name ⇒ String
Name.
-
#page ⇒ Page
Page proving the issue.
-
#platform_name ⇒ Symbol
Name of the vulnerable platform.
-
#platform_type ⇒ Symbol
Type of the vulnerable platform.
-
#proof ⇒ String
Data that was matched by the #signature.
-
#references ⇒ Hash
References related to the issue.
-
#referring_page ⇒ Page
Page containing the #vector and whose audit resulted in the discovery of the issue.
-
#remarks ⇒ Hash
Remarks about the issue.
-
#remedy_code ⇒ String
Code snippet demonstrating how to remedy the Issue.
-
#remedy_guidance ⇒ String
Brief text explaining how to remedy the issue.
-
#severity ⇒ String
Severity of the issue.
-
#signature ⇒ String
The signature/pattern that identified the issue.
-
#tags ⇒ Array<String>
Tags categorizing the issue.
-
#trusted ⇒ Bool
‘true` if the issue can be trusted (doesn’t require manual verification), ‘false` otherwise.
-
#variations ⇒ Array<Issue>
Variations of this issue.
-
#vector ⇒ Element::Base?
Instance of the relevant vector if available.
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#active? ⇒ Boolean
‘true` if the issue was discovered by manipulating an input, `false` otherwise.
-
#add_remark(author, string) ⇒ Object
Adds a remark as a heads-up to the end user.
-
#affected_input_name ⇒ String?
The name of the affected input, ‘nil` if the issue is #passive?.
- #as_variation ⇒ Issue
-
#cwe_url ⇒ String
CWE reference URL.
-
#digest ⇒ Integer
A hash uniquely identifying this issue.
- #eql?(other) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(options = {}) ⇒ Issue
constructor
A new instance of Issue.
-
#passive? ⇒ Boolean
‘true` if the issue was discovered passively, `false` otherwise.
- #request ⇒ HTTP::Request
- #response ⇒ HTTP::Response
-
#solo? ⇒ Bool
‘true` if the issue neither has nor is a variation, `false` otherwise.
- #to_h ⇒ Hash (also: #to_hash)
-
#to_rpc_data ⇒ Hash
Data representing this instance that are suitable the RPC transmission.
-
#to_solo(issue) ⇒ Issue
Copy of ‘self` as a solo issue.
-
#to_solo!(issue) ⇒ Issue
Converts ‘self` to a solo issue, in place.
-
#trusted? ⇒ Bool
‘true` if the issue can be trusted (doesn’t require manual verification), ‘false` otherwise.
-
#unique_id ⇒ String
A string uniquely identifying this issue.
- #untrusted? ⇒ Boolean
-
#variation? ⇒ Bool
‘true` if `self` is a variation.
-
#with_variations ⇒ Issue
A copy of ‘self` without specific details and an empty array of #variations to be populated.
Constructor Details
#initialize(options = {}) ⇒ Issue
Returns a new instance of Issue.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/arachni/issue.rb', line 117 def initialize( = {} ) # Make sure we're dealing with UTF-8 data. = .recode .each do |k, v| send( "#{k.to_s.downcase}=", v ) end fail ArgumentError, 'Missing :vector' if !@vector @remarks ||= {} @trusted = true if @trusted.nil? @references ||= {} @tags ||= [] @variations ||= [] @variation = nil end |
Instance Attribute Details
#check ⇒ Hash
Returns Information about the check that logged the issue.
91 92 93 |
# File 'lib/arachni/issue.rb', line 91 def check @check end |
#cwe ⇒ String
Returns The CWE ID number of the issue.
62 63 64 |
# File 'lib/arachni/issue.rb', line 62 def cwe @cwe end |
#description ⇒ String
Should be treated as Markdown.
Returns Brief description.
32 33 34 |
# File 'lib/arachni/issue.rb', line 32 def description @description end |
#page ⇒ Page
Returns Page proving the issue.
87 88 89 |
# File 'lib/arachni/issue.rb', line 87 def page @page end |
#platform_name ⇒ Symbol
Returns Name of the vulnerable platform.
68 69 70 |
# File 'lib/arachni/issue.rb', line 68 def platform_name @platform_name end |
#platform_type ⇒ Symbol
Returns Type of the vulnerable platform.
74 75 76 |
# File 'lib/arachni/issue.rb', line 74 def platform_type @platform_type end |
#proof ⇒ String
Returns Data that was matched by the #signature.
99 100 101 |
# File 'lib/arachni/issue.rb', line 99 def proof @proof end |
#references ⇒ Hash
Returns References related to the issue.
56 57 58 |
# File 'lib/arachni/issue.rb', line 56 def references @references end |
#referring_page ⇒ Page
Returns Page containing the #vector and whose audit resulted in the discovery of the issue.
83 84 85 |
# File 'lib/arachni/issue.rb', line 83 def referring_page @referring_page end |
#remarks ⇒ Hash
Returns Remarks about the issue. Key is the name of the entity which made the remark, value is an ‘Array` of remarks.
109 110 111 |
# File 'lib/arachni/issue.rb', line 109 def remarks @remarks end |
#remedy_code ⇒ String
Returns Code snippet demonstrating how to remedy the Issue.
42 43 44 |
# File 'lib/arachni/issue.rb', line 42 def remedy_code @remedy_code end |
#remedy_guidance ⇒ String
Should be treated as Markdown.
Returns Brief text explaining how to remedy the issue.
38 39 40 |
# File 'lib/arachni/issue.rb', line 38 def remedy_guidance @remedy_guidance end |
#severity ⇒ String
Returns Severity of the issue.
48 49 50 |
# File 'lib/arachni/issue.rb', line 48 def severity @severity end |
#signature ⇒ String
Returns The signature/pattern that identified the issue.
95 96 97 |
# File 'lib/arachni/issue.rb', line 95 def signature @signature end |
#tags ⇒ Array<String>
Returns Tags categorizing the issue.
52 53 54 |
# File 'lib/arachni/issue.rb', line 52 def @tags end |
#trusted ⇒ Bool
Returns ‘true` if the issue can be trusted (doesn’t require manual verification), ‘false` otherwise.
104 105 106 |
# File 'lib/arachni/issue.rb', line 104 def trusted @trusted end |
#variations ⇒ Array<Issue>
Returns Variations of this issue.
113 114 115 |
# File 'lib/arachni/issue.rb', line 113 def variations @variations end |
#vector ⇒ Element::Base?
Returns Instance of the relevant vector if available.
78 79 80 |
# File 'lib/arachni/issue.rb', line 78 def vector @vector end |
Class Method Details
.from_rpc_data(data) ⇒ Issue
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/arachni/issue.rb', line 450 def self.from_rpc_data( data ) instance = allocate data.each do |name, value| value = case name when 'vector' element_string_to_class( value.delete('class') ).from_rpc_data( value ) when 'check' if value['elements'] value['elements'] = (value['elements'].map do |class_name| element_string_to_class( class_name ) end) end value.my_symbolize_keys(false) when 'variations' value.map { |i| from_rpc_data i } when 'remarks' value.my_symbolize_keys when 'platform_name', 'platform_type' next if !value value.to_sym when 'severity' next if value.to_s.empty? Severity.const_get( value.upcase.to_sym ) when 'page', 'referring_page' Arachni::Page.from_rpc_data( value ) else value end instance.instance_variable_set( "@#{name}", value ) end instance end |
Instance Method Details
#==(other) ⇒ Object
411 412 413 |
# File 'lib/arachni/issue.rb', line 411 def ==( other ) hash == other.hash end |
#active? ⇒ Boolean
Returns ‘true` if the issue was discovered by manipulating an input, `false` otherwise.
165 166 167 168 169 170 171 |
# File 'lib/arachni/issue.rb', line 165 def active? if variations && variations.any? return variations.first.active? end !!(vector.respond_to?( :affected_input_name ) && vector.affected_input_name) end |
#add_remark(author, string) ⇒ Object
Adds a remark as a heads-up to the end user.
153 154 155 156 157 158 |
# File 'lib/arachni/issue.rb', line 153 def add_remark( , string ) fail ArgumentError, 'Author cannot be blank.' if .to_s.empty? fail ArgumentError, 'String cannot be blank.' if string.to_s.empty? (@remarks[] ||= []) << string end |
#affected_input_name ⇒ String?
Returns The name of the affected input, ‘nil` if the issue is #passive?.
177 178 179 180 181 182 183 184 185 |
# File 'lib/arachni/issue.rb', line 177 def affected_input_name return if !active? if variations && variations.any? return variations.first.vector.affected_input_name end vector.affected_input_name end |
#as_variation ⇒ Issue
367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/arachni/issue.rb', line 367 def as_variation issue = self.deep_clone instance_variables.each do |k| next if k == :@vector || VARIATION_ATTRIBUTES.include?( k ) || !issue.instance_variable_defined?( k ) issue.remove_instance_variable k end issue.unique_id = unique_id issue.variation = true issue end |
#cwe_url ⇒ String
Returns CWE reference URL.
217 218 219 220 |
# File 'lib/arachni/issue.rb', line 217 def cwe_url return if !cwe @cwe_url ||= "http://cwe.mitre.org/data/definitions/#{cwe}.html".freeze end |
#digest ⇒ Integer
Returns A hash uniquely identifying this issue.
326 327 328 |
# File 'lib/arachni/issue.rb', line 326 def digest unique_id.persistent_hash end |
#eql?(other) ⇒ Boolean
419 420 421 |
# File 'lib/arachni/issue.rb', line 419 def eql?( other ) hash == other.hash end |
#hash ⇒ Object
415 416 417 |
# File 'lib/arachni/issue.rb', line 415 def hash unique_id.hash end |
#passive? ⇒ Boolean
Returns ‘true` if the issue was discovered passively, `false` otherwise.
191 192 193 |
# File 'lib/arachni/issue.rb', line 191 def passive? !active? end |
#request ⇒ HTTP::Request
142 143 144 145 |
# File 'lib/arachni/issue.rb', line 142 def request return if !response response.request end |
#response ⇒ HTTP::Response
136 137 138 139 |
# File 'lib/arachni/issue.rb', line 136 def response return if !page page.response end |
#solo? ⇒ Bool
Returns ‘true` if the issue neither has nor is a variation, `false` otherwise.
332 333 334 |
# File 'lib/arachni/issue.rb', line 332 def solo? @variation.nil? end |
#to_h ⇒ Hash Also known as: to_hash
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/arachni/issue.rb', line 246 def to_h h = {} self.instance_variables.each do |var| h[normalize_name( var )] = try_dup( instance_variable_get( var ) ) end h[:vector] = vector.to_h h.delete( :unique_id ) if solo? h.delete( :variation ) else if variation? h[:vector].delete :html h[:vector].delete :type h[:vector].delete :url h[:vector].delete :action h[:vector].delete :default_inputs h[:vector].delete :affected_input_name else h[:vector][:inputs] = h[:vector].delete( :default_inputs ) h[:vector][:affected_input_name] = affected_input_name end end if !variation? || solo? h[:digest] = digest h[:severity] = severity.to_sym h[:cwe_url] = cwe_url if cwe_url # Since we're doing the whole cross-platform hash thing better switch # the Element classes in the check's info data to symbols. h[:check][:elements] ||= [] h[:check][:elements] = h[:check][:elements].map(&:type) h[:variations] = @variations.map(&:to_h) end if variation? || solo? if page dom_h = page.dom.to_h dom_h.delete(:skip_states) h[:page] = { body: page.body, dom: dom_h } end if referring_page referring_page_dom_h = referring_page.dom.to_h referring_page_dom_h.delete(:skip_states) h[:referring_page] = { body: referring_page.body, dom: referring_page_dom_h } end h[:response] = response.to_h if response h[:request] = request.to_h if request end h end |
#to_rpc_data ⇒ Hash
Returns Data representing this instance that are suitable the RPC transmission.
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/arachni/issue.rb', line 425 def to_rpc_data data = {} instance_variables.each do |ivar| data[ivar.to_s.gsub('@','')] = instance_variable_get( ivar ).to_rpc_data_or_self end if data['check'] && data['check'][:elements] data['check'] = data['check'].dup data['check'][:elements] = data['check'][:elements].map(&:to_s) end if data['variations'] data['variations'] = data['variations'].map(&:to_rpc_data) end data['digest'] = digest data['severity'] = data['severity'].to_s data end |
#to_solo(issue) ⇒ Issue
Copy of ‘self` as a solo issue.
407 408 409 |
# File 'lib/arachni/issue.rb', line 407 def to_solo( issue ) deep_clone.to_solo!( issue ) end |
#to_solo!(issue) ⇒ Issue
Converts ‘self` to a solo issue, in place.
388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/arachni/issue.rb', line 388 def to_solo!( issue ) issue.instance_variables.each do |k| next if k == :@variations || k == :@vector || k == :@trusted next if (val = issue.instance_variable_get(k)).nil? instance_variable_set( k, val ) end @variations = [] @variation = nil self end |
#trusted? ⇒ Bool
Returns ‘true` if the issue can be trusted (doesn’t require manual verification), ‘false` otherwise.
200 201 202 |
# File 'lib/arachni/issue.rb', line 200 def trusted? !!@trusted end |
#unique_id ⇒ String
Returns A string uniquely identifying this issue.
316 317 318 319 320 |
# File 'lib/arachni/issue.rb', line 316 def unique_id return @unique_id if @unique_id vector_info = active? ? "#{vector.method}:#{vector.affected_input_name}:" : nil "#{name}:#{vector_info}#{vector.action.split( '?' ).first}" end |
#untrusted? ⇒ Boolean
205 206 207 |
# File 'lib/arachni/issue.rb', line 205 def untrusted? !trusted? end |
#variation? ⇒ Bool
Returns ‘true` if `self` is a variation.
338 339 340 |
# File 'lib/arachni/issue.rb', line 338 def variation? !!@variation end |
#with_variations ⇒ Issue
Returns A copy of ‘self` without specific details and an empty array of #variations to be populated.
Also, the #vector attribute will hold the original, non-mutated vector.
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/arachni/issue.rb', line 347 def with_variations issue = self.deep_clone instance_variables.each do |k| next if k == :@trusted || !VARIATION_ATTRIBUTES.include?( k ) || !issue.instance_variable_defined?( k ) issue.remove_instance_variable k end issue.vector.reset issue.unique_id = unique_id issue.variation = false issue end |