-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvuln.rb
118 lines (103 loc) · 3.69 KB
/
vuln.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
module Appspider
# This class represents each of the vulnerabilities reported in the
# AppSpider VulnerabilitiesSummary.xml file as <Vuln> entities.
#
# It provides a convenient way to access the information scattered all over
# the XML entities.
#
# Instead of providing separate methods for each supported property we rely
# on Ruby's #method_missing to do most of the work.
class Vuln
attr_accessor :xml
# Accepts an XML node from Nokogiri::XML.
def initialize(xml_node)
@xml = xml_node
end
# List of supported tags. They can be attributes, simple descendants or
# collections (e.g. <references/>, <tags/>)
def supported_tags
[
# attributes
# simple tags
:attack_class, :attack_score, :attack_type, :attack_value, :capec,
:cwe_id, :description, :dissa_asc, :normalized_url, :oval, :owasp2007,
:owasp2010, :owasp2013, :recommendation, :vuln_method, :vuln_param,
:vuln_type, :vuln_url, :web_site
# nested tags
]
end
# This allows external callers (and specs) to check for implemented
# properties
def respond_to?(method, include_private=false)
return true if supported_tags.include?(method.to_sym)
super
end
# This method is invoked by Ruby when a method that is not defined in this
# instance is called.
#
# In our case we inspect the @method@ parameter and try to find the
# 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
# exception
unless supported_tags.include?(method)
super
return
end
# First we try the attributes. In Ruby we use snake_case, but in XML
# CamelCase is used for some attributes
translations_table = {
capec: 'CAPEC',
dissa_asc: 'DISSA_ASC',
owasp2007: 'OWASP2007',
owasp2010: 'OWASP2010',
owasp2013: 'OWASP2013',
oval: 'OVAL',
wasc: 'WASC'
}
method_name = translations_table.fetch(method, method.to_s.camelcase)
# no attributes in the <issue> node
# return @xml.attributes[method_name].value if @xml.attributes.key?(method_name)
# Then we try simple children tags: name, type, ...
tag = @xml.at_xpath("./#{method_name}")
if tag && !tag.text.blank?
if tags_with_html_content.include?(method)
return cleanup_html(tag.text)
else
return tag.text
end
else
# nothing found, the tag is valid but not present in this Vuln
return nil
end
end
private
def cleanup_html(source)
result = source.dup
result.gsub!(/"/, '"')
result.gsub!(/&/, '&')
result.gsub!(/</, '<')
result.gsub!(/>/, '>')
result.gsub!(/<b>(.*?)<\/b>/, '*\1*')
result.gsub!(/<br\/>/, "\n")
result.gsub!(/<br>/, "\n")
result.gsub!(/<font.*?>(.*?)<\/font>/m, '\1')
result.gsub!(/<h2>(.*?)<\/h2>/, '*\1*')
result.gsub!(/<i>(.*?)<\/i>/, '\1')
result.gsub!(/<p>(.*?)<\/p>/m, '\1')
result.gsub!(/<pre.*?>(.*?)<\/pre>/m){|m| "\n\nbc.. #{ $1 }\n\np. \n" }
result.gsub!(/<ul>/, "\n")
result.gsub!(/<\/ul>/, "\n")
result.gsub!(/<li>/, "\n* ")
result.gsub!(/<\/li>/, "\n")
result
end
# Some of the values have embedded HTML content that we need to strip
def tags_with_html_content
[:description, :recommendation]
end
end
end