diff --git a/CHANGELOG.md b/CHANGELOG.md index 889d59c..cf9967c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ v4.12.0 (XXXX 2024) + - Parse code tags as inline code - Update Dradis links in README v4.11.0 (January 2024) diff --git a/lib/nexpose/vulnerability.rb b/lib/nexpose/vulnerability.rb index 6363f83..25f22e8 100644 --- a/lib/nexpose/vulnerability.rb +++ b/lib/nexpose/vulnerability.rb @@ -20,7 +20,7 @@ def initialize(xml_node) def supported_tags [ # attributes - :added, :cvss_score, :cvss_vector, :modified, :nexpose_id, :pci_severity, + :added, :cvss_score, :cvss_vector, :modified, :nexpose_id, :pci_severity, :published, :risk_score, :severity, :title, # simple tags @@ -34,10 +34,9 @@ def supported_tags ] end - # This allows external callers (and specs) to check for implemented # properties - def respond_to?(method, include_private=false) + def respond_to?(method, include_private = false) return true if supported_tags.include?(method.to_sym) super end @@ -49,7 +48,6 @@ def respond_to?(method, include_private=false) # attribute, simple descendent or collection that it maps to in the XML # tree. def method_missing(method, *args) - # We could remove this check and return nil for any non-recognized tag. # The problem would be that it would make tricky to debug problems with # typos. For instance: <>.potr would return nil instead of raising an @@ -62,11 +60,11 @@ def method_missing(method, *args) # First we try the attributes. In Ruby we use snake_case, but in XML # CamelCase is used for some attributes translations_table = { - :nexpose_id => 'id', - :pci_severity => 'pciSeverity', - :risk_score => 'riskScore', - :cvss_score => 'cvssScore', - :cvss_vector =>'cvssVector' + nexpose_id: 'id', + pci_severity: 'pciSeverity', + risk_score: 'riskScore', + cvss_score: 'cvssScore', + cvss_vector: 'cvssVector' } method_name = translations_table.fetch(method, method.to_s) @@ -96,7 +94,7 @@ def method_missing(method, *args) return @xml.xpath("//test[@id='#{vuln_id}']/Paragraph"). text.split("\n"). collect(&:strip). - reject{|line| line.empty?}.join("\n") + reject { |line| line.empty? }.join("\n") end nil @@ -106,13 +104,13 @@ def method_missing(method, *args) def add_bc_to_ssl_cipher_list(source) result = source.to_s - result.gsub!(/\n(.*?)!(.*?)/){"\nbc. #{ $1 }!#{ $2 }\n"} + result.gsub!(/\n(.*?)!(.*?)/) { "\nbc. #{ $1 }!#{ $2 }\n" } result end def cleanup_html(source) result = source.to_s - result.gsub!(/(.*?)<\/ContainerBlockElement>/m){|m| "#{ $1 }"} + result.gsub!(/(.*?)<\/ContainerBlockElement>/m) { |m| "#{ $1 }" } result.gsub!(/(\s*)(.*?)<\/Paragraph>(\s*)<\/Paragraph>/mi) do text = $2 text[/\n/] ? "\nbc.. #{ text }\n\np. " : "@#{text}@" @@ -121,10 +119,11 @@ def cleanup_html(source) text = $1 text[/\n/] ? "\nbc.. #{ text }\n\np. " : "@#{text}@" end - result.gsub!(/(.*?)<\/Paragraph>/m){|m| "#{ $1 }\n"} + result.gsub!(/(.*?)<\/code>/) { "@#{ $1 }@" } + result.gsub!(/(.*?)<\/Paragraph>/m) { |m| "#{ $1 }\n" } result.gsub!(/|<\/Paragraph>/, '') - result.gsub!(/(.*?)<\/UnorderedList>/m){|m| "#{ $2 }"} - result.gsub!(/(.*?)<\/OrderedList>/m){|m| "#{ $2 }"} + result.gsub!(/(.*?)<\/UnorderedList>/m) { |m| "#{ $2 }" } + result.gsub!(/(.*?)<\/OrderedList>/m) { |m| "#{ $2 }" } result.gsub!(/|<\/ListItem>/, '') result.gsub!(/ /, '') result.gsub!(/ /, '') @@ -141,10 +140,10 @@ def cleanup_nested(source) result = source.to_s result.gsub!(//, '') result.gsub!(/<\/references>/, '') - result.gsub!(/(.*?)<\/reference>/i) {"#{$1.strip}: #{$2.strip}\n"} + result.gsub!(/(.*?)<\/reference>/i) { "#{$1.strip}: #{$2.strip}\n" } result.gsub!(//, '') result.gsub!(/<\/tags>/, '') - result.gsub!(/(.*?)<\/tag>/) {"#{$1}\n"} + result.gsub!(/(.*?)<\/tag>/) { "#{$1}\n" } result.gsub!(/ /, '') result end @@ -156,6 +155,5 @@ def tags_with_html_content def tags_with_nested_content [:references, :tags] end - end end diff --git a/spec/fixtures/files/full.xml b/spec/fixtures/files/full.xml index a8868dc..d6d2d94 100644 --- a/spec/fixtures/files/full.xml +++ b/spec/fixtures/files/full.xml @@ -68,7 +68,7 @@ - A flaw was found in the default error response for status code 400. This flaw could be used by an attacker to expose "httpOnly" cookies when no custom ErrorDocument is specified. + A flaw was found in the default error response for status code 400. This flaw could be used by an attacker to expose httpOnly cookies when no custom ErrorDocument is specified. diff --git a/spec/nexpose_upload_spec.rb b/spec/nexpose_upload_spec.rb index 78f40eb..f8e78e7 100644 --- a/spec/nexpose_upload_spec.rb +++ b/spec/nexpose_upload_spec.rb @@ -170,7 +170,7 @@ expect(args[:content]).to include("#[Content]#\nThe following NTP variables") OpenStruct.new(args) end.once - + expect(@content_service).to receive(:create_evidence) do |args| expect(args[:content]).to include("#[Content]#\nVulnerable URL:") OpenStruct.new(args) @@ -187,6 +187,15 @@ @importer.import(file: @fixtures_dir + '/full.xml') end + + it 'transforms the markup' do + expect(@content_service).to receive(:create_issue) do |args| + expect(args[:text]).to include('@httpOnly@') + OpenStruct.new(args) + end + + @importer.import(file: @fixtures_dir + '/full.xml') + end end describe 'Importer: Full with duplicate nodes' do