cve_crawler 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c5c9a85897586ed3cf7cc66e9e97b9b7b09269b
4
- data.tar.gz: 14af3dafda87aef7f5697c5d0b080036a9dc2488
3
+ metadata.gz: 5bb15083b60b4fdb80817982843e88e41af0e47c
4
+ data.tar.gz: e6b894f461ed3d6d452cf60bdde31979cf5db551
5
5
  SHA512:
6
- metadata.gz: 272da0467bb4e39f284a810e6d304929cb12085cb57e838387e6d2042613f75541b1ba8af882d004ef7bfc7be0c377dde054732d373488cb8f5fc0dd3e1a891c
7
- data.tar.gz: d319e15080382fec62bf9a36452b94b35c0f9969687fcd19a23e45c29639e28b83b8733defce524cb347cee7c7a9c78a405b8faae4b9f4dbe49b77e4b3a0d8b6
6
+ metadata.gz: 6e7fde51cb8b3c79811d2df649cab980f87929babd1e0d3dbc3766edaa3366865135742c2ccc7a33fb7500c6f93dc76a6f804f54f99a0ab484d90b8c5dcc91ec
7
+ data.tar.gz: ffe61027502d9a44c491e30faa142548cc58f197aff9bab1eebf2908b1b13d085d6804abf350f4dfeffe23851437e0c341b254e7996f55d7434fa21e535292d1
@@ -1,11 +1,11 @@
1
1
  require 'time'
2
- require 'cve_crawler'
3
- require 'cve_parser'
2
+ require 'cve_crawler/cve_crawler'
3
+ require 'cve_crawler/cve_parser'
4
4
 
5
5
  module CVE
6
6
  VERSION_MAJOR = 0
7
7
  VERSION_MINOR = 1
8
- VERSION_BUILD = 0
8
+ VERSION_BUILD = 1
9
9
  VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_BUILD}".freeze
10
10
 
11
11
  class Core
@@ -1,37 +1,37 @@
1
- require 'net/https'
2
- require 'uri'
3
-
4
- module CVE
5
- class Crawler
6
- DATA_FEED_DEFAULT = URI('https://nvd.nist.gov/download/nvd-rss.xml')
7
- DATA_FEED_ANALYZED = URI('https://nvd.nist.gov/download/nvd-rss-analyzed.xml')
8
-
9
- def initialize(type, verify_cert, user_agent)
10
- @crawl_url = type.downcase == 'analyzed' ? DATA_FEED_ANALYZED : DATA_FEED_DEFAULT
11
- @verify_cert = verify_cert ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
12
- @user_agent = user_agent
13
- end
14
-
15
- attr_reader :crawl_url, :verify_cert, :user_agent
16
-
17
- def crawl
18
- http = Net::HTTP.new(@crawl_url.host, @crawl_url.port)
19
- http.use_ssl = @crawl_url.scheme == 'https'
20
-
21
- if http.use_ssl?
22
- http.verify_mode = @verify_cert
23
- end
24
-
25
- request = Net::HTTP::Get.new(@crawl_url, {'User-Agent' => @user_agent})
26
- response = http.request(request)
27
-
28
- response.value # Raise an error if status is not 200
29
-
30
- response
31
- end
32
-
33
- def inspect
34
- "#<CVE::Crawler url=#{@crawl_url.to_s}>"
35
- end
36
- end
37
- end
1
+ require 'net/https'
2
+ require 'uri'
3
+
4
+ module CVE
5
+ class Crawler
6
+ DATA_FEED_DEFAULT = URI('https://nvd.nist.gov/download/nvd-rss.xml')
7
+ DATA_FEED_ANALYZED = URI('https://nvd.nist.gov/download/nvd-rss-analyzed.xml')
8
+
9
+ def initialize(type, verify_cert, user_agent)
10
+ @crawl_url = type.downcase == 'analyzed' ? DATA_FEED_ANALYZED : DATA_FEED_DEFAULT
11
+ @verify_cert = verify_cert ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
12
+ @user_agent = user_agent
13
+ end
14
+
15
+ attr_reader :crawl_url, :verify_cert, :user_agent
16
+
17
+ def crawl
18
+ http = Net::HTTP.new(@crawl_url.host, @crawl_url.port)
19
+ http.use_ssl = @crawl_url.scheme == 'https'
20
+
21
+ if http.use_ssl?
22
+ http.verify_mode = @verify_cert
23
+ end
24
+
25
+ request = Net::HTTP::Get.new(@crawl_url, {'User-Agent' => @user_agent})
26
+ response = http.request(request)
27
+
28
+ response.value # Raise an error if status is not 200
29
+
30
+ response
31
+ end
32
+
33
+ def inspect
34
+ "#<CVE::Crawler url=#{@crawl_url.to_s}>"
35
+ end
36
+ end
37
+ end
@@ -1,35 +1,35 @@
1
- module CVE
2
- class Filter
3
- def initialize(history_size=100)
4
- @history = []
5
- @history_size = history_size
6
- end
7
-
8
- attr_reader :history_size
9
-
10
- def filter(contents)
11
- return true unless contents.is_a?(Vulnerability)
12
- return true if cve_exists?(contents.identifier)
13
-
14
- history_check_limit
15
- false
16
- end
17
-
18
- def cve_exists?(identifier)
19
- return true if @history.include?(identifier)
20
-
21
- @history << identifier
22
- false
23
- end
24
-
25
- def history_check_limit
26
- if @history.length >= @history_size
27
- @history.drop((@history_size / 2).round)
28
- end
29
- end
30
-
31
- def inspect
32
- "#<CVE::Filter history=#{@history.count} limit=#{@history_size}>"
33
- end
34
- end
35
- end
1
+ module CVE
2
+ class Filter
3
+ def initialize(history_size=100)
4
+ @history = []
5
+ @history_size = history_size
6
+ end
7
+
8
+ attr_reader :history_size
9
+
10
+ def filter(contents)
11
+ return true unless contents.is_a?(Vulnerability)
12
+ return true if cve_exists?(contents.identifier)
13
+
14
+ history_check_limit
15
+ false
16
+ end
17
+
18
+ def cve_exists?(identifier)
19
+ return true if @history.include?(identifier)
20
+
21
+ @history << identifier
22
+ false
23
+ end
24
+
25
+ def history_check_limit
26
+ if @history.length >= @history_size
27
+ @history.drop((@history_size / 2).round)
28
+ end
29
+ end
30
+
31
+ def inspect
32
+ "#<CVE::Filter history=#{@history.count} limit=#{@history_size}>"
33
+ end
34
+ end
35
+ end
@@ -1,74 +1,74 @@
1
- require 'rss'
2
- require 'cve_filter'
3
- require 'cve_vulnerability'
4
-
5
- module CVE
6
- class Parser
7
- def initialize(filters=nil)
8
- @filters = []
9
-
10
- @filters << CVE::Filter.new
11
- @filters << filters if filters
12
- end
13
-
14
- def parse(content)
15
- results = parse_rss_feed(content)
16
-
17
- filter(results)
18
- end
19
-
20
- def parse_rss_feed(content)
21
- rss = RSS::Parser.parse(content)
22
-
23
- parse_items(rss)
24
- end
25
-
26
- def parse_items(rss)
27
- items = []
28
-
29
- if rss.nil?
30
- raise 'RSS object failed to parse, is it valid XML?'
31
- end
32
-
33
- rss.items.each do |item|
34
- items << parse_item(item)
35
- end
36
-
37
- items
38
- end
39
-
40
- def parse_item(item)
41
- CVE::Vulnerability.new({
42
- :identifier => extract_cve_identifier(item.title),
43
- :title => item.title,
44
- :link => item.link,
45
- :description => item.description,
46
- :date => item.date
47
- })
48
- end
49
-
50
- def extract_cve_identifier(title)
51
- title.split(' ')[0]
52
- end
53
-
54
- def filter(results)
55
- filtered_contents = []
56
-
57
- results.each do |result|
58
- result_ok = true
59
-
60
- @filters.each do |filter|
61
- result_ok = result_ok && !filter.filter(result)
62
- end
63
-
64
- filtered_contents << result if result_ok
65
- end
66
-
67
- filtered_contents
68
- end
69
-
70
- def inspect
71
- "<CVE::Parser filters=#{@filters.inspect}>"
72
- end
73
- end
74
- end
1
+ require 'rss'
2
+ require 'cve_crawler/cve_filter'
3
+ require 'cve_crawler/cve_vulnerability'
4
+
5
+ module CVE
6
+ class Parser
7
+ def initialize(filters=nil)
8
+ @filters = []
9
+
10
+ @filters << CVE::Filter.new
11
+ @filters << filters if filters
12
+ end
13
+
14
+ def parse(content)
15
+ results = parse_rss_feed(content)
16
+
17
+ filter(results)
18
+ end
19
+
20
+ def parse_rss_feed(content)
21
+ rss = RSS::Parser.parse(content)
22
+
23
+ parse_items(rss)
24
+ end
25
+
26
+ def parse_items(rss)
27
+ items = []
28
+
29
+ if rss.nil?
30
+ raise 'RSS object failed to parse, is it valid XML?'
31
+ end
32
+
33
+ rss.items.each do |item|
34
+ items << parse_item(item)
35
+ end
36
+
37
+ items
38
+ end
39
+
40
+ def parse_item(item)
41
+ CVE::Vulnerability.new({
42
+ :identifier => extract_cve_identifier(item.title),
43
+ :title => item.title,
44
+ :link => item.link,
45
+ :description => item.description,
46
+ :date => item.date
47
+ })
48
+ end
49
+
50
+ def extract_cve_identifier(title)
51
+ title.split(' ')[0]
52
+ end
53
+
54
+ def filter(results)
55
+ filtered_contents = []
56
+
57
+ results.each do |result|
58
+ result_ok = true
59
+
60
+ @filters.each do |filter|
61
+ result_ok = result_ok && !filter.filter(result)
62
+ end
63
+
64
+ filtered_contents << result if result_ok
65
+ end
66
+
67
+ filtered_contents
68
+ end
69
+
70
+ def inspect
71
+ "<CVE::Parser filters=#{@filters.inspect}>"
72
+ end
73
+ end
74
+ end
@@ -1,62 +1,62 @@
1
- module CVE
2
- class Vulnerability
3
- SOFTWARE_EXTRACT_REGEXP = Regexp.new('[(, ]([^(), ]+)')
4
-
5
- def initialize(data)
6
- unless data.instance_of?(Hash)
7
- raise 'CVE Vulnerability needs to be initialized with a hash'
8
- end
9
-
10
- if malformed?(data)
11
- raise 'CVE Vulnerability data is malformed'
12
- end
13
-
14
- @identifier = data[:identifier]
15
- @date = data[:date]
16
- @description = data[:description]
17
- @link = data[:link]
18
- @title = data[:title]
19
- @affected_software = extract_software_from_title(data[:title])
20
- end
21
-
22
- attr_reader :identifier, :date, :description, :link, :title, :affected_software
23
-
24
- def malformed?(data)
25
- !(data.has_key?(:identifier) && data.has_key?(:date) && data.has_key?(:description) &&
26
- data.has_key?(:link) && data.has_key?(:title))
27
- end
28
-
29
- def extract_software_from_title(title)
30
- software = []
31
-
32
- title.scan(SOFTWARE_EXTRACT_REGEXP) do |scan|
33
- software << scan[0]
34
- end
35
-
36
- software.count == 0 ? nil : software
37
- end
38
-
39
- def affected_count
40
- @affected_software.nil? ? 0 : @affected_software.count
41
- end
42
-
43
- def equal?(cve_item, strict=false)
44
- return false unless cve_item.is_a?(Vulnerability)
45
-
46
- if strict
47
- return @identifier == cve_item.identifier && @link == cve_item.link && @date.utc.iso8601 == cve_item.date.utc.iso8601 &&
48
- @title == cve_item.title && @description == cve_item.description
49
- end
50
-
51
- @identifier == cve_item.identifier && @link == cve_item.link
52
- end
53
-
54
- def to_s
55
- "#{@title} - #{@link}"
56
- end
57
-
58
- def inspect
59
- "#<CVE::Vulnerability id=#{@identifier} affected=#{affected_count}>"
60
- end
61
- end
62
- end
1
+ module CVE
2
+ class Vulnerability
3
+ SOFTWARE_EXTRACT_REGEXP = Regexp.new('[(, ]([^(), ]+)')
4
+
5
+ def initialize(data)
6
+ unless data.instance_of?(Hash)
7
+ raise 'CVE Vulnerability needs to be initialized with a hash'
8
+ end
9
+
10
+ if malformed?(data)
11
+ raise 'CVE Vulnerability data is malformed'
12
+ end
13
+
14
+ @identifier = data[:identifier]
15
+ @date = data[:date]
16
+ @description = data[:description]
17
+ @link = data[:link]
18
+ @title = data[:title]
19
+ @affected_software = extract_software_from_title(data[:title])
20
+ end
21
+
22
+ attr_reader :identifier, :date, :description, :link, :title, :affected_software
23
+
24
+ def malformed?(data)
25
+ !(data.has_key?(:identifier) && data.has_key?(:date) && data.has_key?(:description) &&
26
+ data.has_key?(:link) && data.has_key?(:title))
27
+ end
28
+
29
+ def extract_software_from_title(title)
30
+ software = []
31
+
32
+ title.scan(SOFTWARE_EXTRACT_REGEXP) do |scan|
33
+ software << scan[0]
34
+ end
35
+
36
+ software.count == 0 ? nil : software
37
+ end
38
+
39
+ def affected_count
40
+ @affected_software.nil? ? 0 : @affected_software.count
41
+ end
42
+
43
+ def equal?(cve_item, strict=false)
44
+ return false unless cve_item.is_a?(Vulnerability)
45
+
46
+ if strict
47
+ return @identifier == cve_item.identifier && @link == cve_item.link && @date.utc.iso8601 == cve_item.date.utc.iso8601 &&
48
+ @title == cve_item.title && @description == cve_item.description
49
+ end
50
+
51
+ @identifier == cve_item.identifier && @link == cve_item.link
52
+ end
53
+
54
+ def to_s
55
+ "#{@title} - #{@link}"
56
+ end
57
+
58
+ def inspect
59
+ "#<CVE::Vulnerability id=#{@identifier} affected=#{affected_count}>"
60
+ end
61
+ end
62
+ end
data/spec/crawler_spec.rb CHANGED
@@ -1,15 +1,15 @@
1
- require_relative 'spec_helper'
2
-
3
- describe CVE::Crawler do
4
- it 'should crawl the analyzed file when constructed with the analyzed type' do
5
- crawler = CVE::Crawler.new('analyzed', false, false)
6
-
7
- expect(crawler.crawl_url).to equal(CVE::Crawler::DATA_FEED_ANALYZED)
8
- end
9
-
10
- it 'should crawl the default file when constructed any non-analyzed type' do
11
- crawler = CVE::Crawler.new('anything', false, false)
12
-
13
- expect(crawler.crawl_url).to equal(CVE::Crawler::DATA_FEED_DEFAULT)
14
- end
15
- end
1
+ require_relative 'spec_helper'
2
+
3
+ describe CVE::Crawler do
4
+ it 'should crawl the analyzed file when constructed with the analyzed type' do
5
+ crawler = CVE::Crawler.new('analyzed', false, false)
6
+
7
+ expect(crawler.crawl_url).to equal(CVE::Crawler::DATA_FEED_ANALYZED)
8
+ end
9
+
10
+ it 'should crawl the default file when constructed any non-analyzed type' do
11
+ crawler = CVE::Crawler.new('anything', false, false)
12
+
13
+ expect(crawler.crawl_url).to equal(CVE::Crawler::DATA_FEED_DEFAULT)
14
+ end
15
+ end
data/spec/parser_spec.rb CHANGED
@@ -1,38 +1,38 @@
1
- require_relative 'spec_helper'
2
-
3
- describe CVE::Parser do
4
- crawler_mock = CrawlerResultMock.new
5
- parser = CVE::Parser.new
6
-
7
- it 'should parse a full xml body with three items and return an array of CVE items' do
8
- result = parser.parse(crawler_mock.xml_full)
9
-
10
- expect(result).to be_a(Array)
11
- expect(result.length).to eq(3)
12
-
13
- all_cve_items = true
14
- result.each do |value|
15
- all_cve_items = all_cve_items && value.is_a?(CVE::Vulnerability)
16
- end
17
-
18
- expect(all_cve_items).to equal(true)
19
- end
20
-
21
- it 'should raise an error when non-xml is passed' do
22
- expect{ parser.parse('Not xml') }.to raise_error(RuntimeError)
23
- end
24
-
25
- it 'should extract the CVE identifier from a title' do
26
- title = VulnerabilityMock.new.title
27
-
28
- expect(parser.extract_cve_identifier(title)).to match(/^CVE\-\d{4}\-\d+$/)
29
- end
30
-
31
- it 'should accept a custom filter' do
32
- CVE::Parser.new(CVE::Filter.new)
33
- end
34
-
35
- it 'should accept an array of custom filters' do
36
- CVE::Parser.new([CVE::Filter.new, CVE::Filter.new])
37
- end
38
- end
1
+ require_relative 'spec_helper'
2
+
3
+ describe CVE::Parser do
4
+ crawler_mock = CrawlerResultMock.new
5
+ parser = CVE::Parser.new
6
+
7
+ it 'should parse a full xml body with three items and return an array of CVE items' do
8
+ result = parser.parse(crawler_mock.xml_full)
9
+
10
+ expect(result).to be_a(Array)
11
+ expect(result.length).to eq(3)
12
+
13
+ all_cve_items = true
14
+ result.each do |value|
15
+ all_cve_items = all_cve_items && value.is_a?(CVE::Vulnerability)
16
+ end
17
+
18
+ expect(all_cve_items).to equal(true)
19
+ end
20
+
21
+ it 'should raise an error when non-xml is passed' do
22
+ expect{ parser.parse('Not xml') }.to raise_error(RuntimeError)
23
+ end
24
+
25
+ it 'should extract the CVE identifier from a title' do
26
+ title = VulnerabilityMock.new.title
27
+
28
+ expect(parser.extract_cve_identifier(title)).to match(/^CVE\-\d{4}\-\d+$/)
29
+ end
30
+
31
+ it 'should accept a custom filter' do
32
+ CVE::Parser.new(CVE::Filter.new)
33
+ end
34
+
35
+ it 'should accept an array of custom filters' do
36
+ CVE::Parser.new([CVE::Filter.new, CVE::Filter.new])
37
+ end
38
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,84 +1,84 @@
1
- require 'rspec'
2
- require_relative File.join('..', 'lib', 'cve_crawler', 'cve_core')
3
-
4
- class CrawlerResultMock
5
- def xml_full
6
- <<-eos
7
- <?xml version="1.0" encoding="UTF-8"?>
8
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/">
9
- <channel rdf:about="http://web.nvd.nist.gov/view/vuln/search">
10
- <title>National Vulnerability Database</title>
11
- <link>http://web.nvd.nist.gov/view/vuln/search</link>
12
- <description>This feed contains the most recent CVE cyber vulnerabilities published within the National Vulnerability Database.</description>
13
- <items>
14
- <rdf:Seq>
15
- <rdf:li rdf:resource="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4476" />
16
- <rdf:li rdf:resource="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4500" />
17
- <rdf:li rdf:resource="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4501" />
18
- </rdf:Seq>
19
- </items>
20
- <dc:date>2015-09-27T04:50:00Z</dc:date>
21
- <dc:language>en-us</dc:language>
22
- <dc:rights>This material is not copywritten and may be freely used, however, attribution is requested.</dc:rights>
23
- </channel>
24
- <item rdf:about="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4476">
25
- <title>CVE-2015-4476 (firefox)</title>
26
- <link>http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4476</link>
27
- <description>Mozilla Firefox before 41.0 on Android allows user-assisted remote attackers to spoof address-bar attributes by leveraging lack of navigation after a paste of a URL with a nonstandard scheme, as demonstrated by spoofing an SSL attribute.</description>
28
- <dc:date>2015-09-24T04:59:00Z</dc:date>
29
- </item>
30
- <item rdf:about="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4500">
31
- <title>CVE-2015-4500 (firefox, firefox_esr)</title>
32
- <link>http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4500</link>
33
- <description>Multiple unspecified vulnerabilities in the browser engine in Mozilla Firefox before 41.0 and Firefox ESR 38.x before 38.3 allow remote attackers to cause a denial of service (memory corruption and application crash) or possibly execute arbitrary code via unknown vectors.</description>
34
- <dc:date>2015-09-24T04:59:02Z</dc:date>
35
- </item>
36
- <item rdf:about="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4501">
37
- <title>CVE-2015-4501 (firefox)</title>
38
- <link>http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4501</link>
39
- <description>Multiple unspecified vulnerabilities in the browser engine in Mozilla Firefox before 41.0 allow remote attackers to cause a denial of service (memory corruption and application crash) or possibly execute arbitrary code via unknown vectors.</description>
40
- <dc:date>2015-09-24T04:59:03Z</dc:date>
41
- </item>
42
- </rdf:RDF>
43
- eos
44
- end
45
- end
46
-
47
- class VulnerabilityMock
48
- def self.generate
49
- mocker = VulnerabilityMock.new
50
- id = mocker.identifier
51
-
52
- CVE::Vulnerability.new({
53
- :identifier => id,
54
- :title => mocker.title(id),
55
- :link => mocker.link(id),
56
- :description => mocker.description,
57
- :date => mocker.date
58
- })
59
- end
60
-
61
- def identifier
62
- year = Time.now.year
63
- "CVE-#{rand(2000..year)}-#{rand(0..9999)}"
64
- end
65
-
66
- def title(id=nil)
67
- (id || identifier) + ' (' + ['Lorem Ipsum', 'Some vulnerability', 'Your favourite software',
68
- 'Firefox', 'Chromium', 'Thunderbird'].sample.split('').shuffle.join + ')'
69
- end
70
-
71
- def link(id=nil)
72
- 'http://web.nvd.nist.gov/view/vuln/detail?vulnId=' + (id || identifier)
73
- end
74
-
75
- def description
76
- ['Hakuna Matata', 'What a wonderful phrase', 'Ain\'t no passing phrase', 'It means no worries',
77
- 'for the rest of your days', 'It\'s our problem-free philosophy', 'Yeah. That\'s our motto',
78
- 'What\'s a motto?'].sample.split('').shuffle.join
79
- end
80
-
81
- def date
82
- Time.now
83
- end
84
- end
1
+ require 'rspec'
2
+ require_relative File.join('..', 'lib', 'cve_crawler')
3
+
4
+ class CrawlerResultMock
5
+ def xml_full
6
+ <<-eos
7
+ <?xml version="1.0" encoding="UTF-8"?>
8
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/">
9
+ <channel rdf:about="http://web.nvd.nist.gov/view/vuln/search">
10
+ <title>National Vulnerability Database</title>
11
+ <link>http://web.nvd.nist.gov/view/vuln/search</link>
12
+ <description>This feed contains the most recent CVE cyber vulnerabilities published within the National Vulnerability Database.</description>
13
+ <items>
14
+ <rdf:Seq>
15
+ <rdf:li rdf:resource="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4476" />
16
+ <rdf:li rdf:resource="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4500" />
17
+ <rdf:li rdf:resource="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4501" />
18
+ </rdf:Seq>
19
+ </items>
20
+ <dc:date>2015-09-27T04:50:00Z</dc:date>
21
+ <dc:language>en-us</dc:language>
22
+ <dc:rights>This material is not copywritten and may be freely used, however, attribution is requested.</dc:rights>
23
+ </channel>
24
+ <item rdf:about="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4476">
25
+ <title>CVE-2015-4476 (firefox)</title>
26
+ <link>http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4476</link>
27
+ <description>Mozilla Firefox before 41.0 on Android allows user-assisted remote attackers to spoof address-bar attributes by leveraging lack of navigation after a paste of a URL with a nonstandard scheme, as demonstrated by spoofing an SSL attribute.</description>
28
+ <dc:date>2015-09-24T04:59:00Z</dc:date>
29
+ </item>
30
+ <item rdf:about="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4500">
31
+ <title>CVE-2015-4500 (firefox, firefox_esr)</title>
32
+ <link>http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4500</link>
33
+ <description>Multiple unspecified vulnerabilities in the browser engine in Mozilla Firefox before 41.0 and Firefox ESR 38.x before 38.3 allow remote attackers to cause a denial of service (memory corruption and application crash) or possibly execute arbitrary code via unknown vectors.</description>
34
+ <dc:date>2015-09-24T04:59:02Z</dc:date>
35
+ </item>
36
+ <item rdf:about="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4501">
37
+ <title>CVE-2015-4501 (firefox)</title>
38
+ <link>http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-4501</link>
39
+ <description>Multiple unspecified vulnerabilities in the browser engine in Mozilla Firefox before 41.0 allow remote attackers to cause a denial of service (memory corruption and application crash) or possibly execute arbitrary code via unknown vectors.</description>
40
+ <dc:date>2015-09-24T04:59:03Z</dc:date>
41
+ </item>
42
+ </rdf:RDF>
43
+ eos
44
+ end
45
+ end
46
+
47
+ class VulnerabilityMock
48
+ def self.generate
49
+ mocker = VulnerabilityMock.new
50
+ id = mocker.identifier
51
+
52
+ CVE::Vulnerability.new({
53
+ :identifier => id,
54
+ :title => mocker.title(id),
55
+ :link => mocker.link(id),
56
+ :description => mocker.description,
57
+ :date => mocker.date
58
+ })
59
+ end
60
+
61
+ def identifier
62
+ year = Time.now.year
63
+ "CVE-#{rand(2000..year)}-#{rand(0..9999)}"
64
+ end
65
+
66
+ def title(id=nil)
67
+ (id || identifier) + ' (' + ['Lorem Ipsum', 'Some vulnerability', 'Your favourite software',
68
+ 'Firefox', 'Chromium', 'Thunderbird'].sample.split('').shuffle.join + ')'
69
+ end
70
+
71
+ def link(id=nil)
72
+ 'http://web.nvd.nist.gov/view/vuln/detail?vulnId=' + (id || identifier)
73
+ end
74
+
75
+ def description
76
+ ['Hakuna Matata', 'What a wonderful phrase', 'Ain\'t no passing phrase', 'It means no worries',
77
+ 'for the rest of your days', 'It\'s our problem-free philosophy', 'Yeah. That\'s our motto',
78
+ 'What\'s a motto?'].sample.split('').shuffle.join
79
+ end
80
+
81
+ def date
82
+ Time.now
83
+ end
84
+ end
@@ -1,137 +1,137 @@
1
- require_relative 'spec_helper'
2
-
3
- describe CVE::Vulnerability do
4
- mocker = VulnerabilityMock.new
5
- cve_vul_obj = VulnerabilityMock.generate
6
-
7
- it 'should not error when passing a valid hash' do
8
- id = mocker.identifier
9
-
10
- item = CVE::Vulnerability.new({
11
- :identifier => id,
12
- :title => mocker.title(id),
13
- :link => mocker.link(id),
14
- :description => mocker.description,
15
- :date => mocker.date
16
- })
17
-
18
- expect(item).to be_a(CVE::Vulnerability)
19
- end
20
-
21
- it 'should compare to a CVE with the same identifier and link' do
22
- id = mocker.identifier
23
- link = mocker.link(id)
24
- item = CVE::Vulnerability.new({
25
- :identifier => id,
26
- :title => mocker.title(id),
27
- :link => link,
28
- :description => mocker.description,
29
- :date => mocker.date
30
- })
31
-
32
- item_roughly_identical = CVE::Vulnerability.new({
33
- :identifier => id,
34
- :title => mocker.title(id),
35
- :link => link,
36
- :description => mocker.description,
37
- :date => mocker.date
38
- })
39
-
40
- expect(item.equal?(item_roughly_identical, false)).to equal(true)
41
- end
42
-
43
- it 'should compare strictly to an identical CVE' do
44
- id = mocker.identifier
45
- item = CVE::Vulnerability.new({
46
- :identifier => id,
47
- :title => mocker.title(id),
48
- :link => mocker.link(id),
49
- :description => mocker.description,
50
- :date => mocker.date
51
- })
52
-
53
- item_identical = item.clone
54
-
55
- expect(item.equal?(item_identical, true)).to equal(true)
56
- end
57
-
58
- it 'should fail compare strictly to an unidentical CVE with the same ID' do
59
- id = mocker.identifier
60
- item = CVE::Vulnerability.new({
61
- :identifier => id,
62
- :title => mocker.title(id),
63
- :link => mocker.link(id),
64
- :description => mocker.description,
65
- :date => mocker.date
66
- })
67
-
68
- item_unidentical = CVE::Vulnerability.new({
69
- :identifier => id,
70
- :title => mocker.title(id),
71
- :link => mocker.link(id),
72
- :description => mocker.description,
73
- :date => mocker.date
74
- })
75
-
76
- expect(item.equal?(item_unidentical, true)).to equal(false)
77
- end
78
-
79
- it 'should fail compare to an unidentical CVE' do
80
- id = mocker.identifier
81
- item = CVE::Vulnerability.new({
82
- :identifier => id,
83
- :title => mocker.title(id),
84
- :link => mocker.link(id),
85
- :description => mocker.description,
86
- :date => mocker.date
87
- })
88
-
89
- id = mocker.identifier
90
- item_unidentical = CVE::Vulnerability.new({
91
- :identifier => id,
92
- :title => mocker.title(id),
93
- :link => mocker.link(id),
94
- :description => mocker.description,
95
- :date => mocker.date
96
- })
97
-
98
- expect(item.equal?(item_unidentical, false)).to equal(false)
99
- end
100
-
101
- it 'should be able to extract a single software from the title' do
102
- title = 'CVE-2015-123 (firefox)'
103
- extract = cve_vul_obj.extract_software_from_title(title)
104
-
105
- expect(extract.count).to eq(1)
106
- expect(extract[0]).to eq('firefox')
107
- end
108
-
109
- it 'should be able to extract many software from the title' do
110
- title = 'CVE-2015-123 (firefox, firefox_esr, flash)'
111
- extract = cve_vul_obj.extract_software_from_title(title)
112
-
113
- expect(extract.count).to eq(3)
114
- expect(extract[0]).to eq('firefox')
115
- expect(extract[1]).to eq('firefox_esr')
116
- expect(extract[2]).to eq('flash')
117
- end
118
-
119
- it 'should return nil for affected software when not included' do
120
- title = 'CVE-2015-123'
121
- extract = cve_vul_obj.extract_software_from_title(title)
122
-
123
- expect(extract).to eq(nil)
124
- end
125
-
126
- it 'should error when not passing a hash' do
127
- expect{ CVE::Vulnerability.new('') }.to raise_error(RuntimeError)
128
- end
129
-
130
- it 'should error when passing an empty hash' do
131
- expect{ CVE::Vulnerability.new({}) }.to raise_error(RuntimeError)
132
- end
133
-
134
- it 'should error when passing a hash with missing keys' do
135
- expect{ CVE::Vulnerability.new({:identifier => 'abc', :title => 'title'}) }.to raise_error(RuntimeError)
136
- end
137
- end
1
+ require_relative 'spec_helper'
2
+
3
+ describe CVE::Vulnerability do
4
+ mocker = VulnerabilityMock.new
5
+ cve_vul_obj = VulnerabilityMock.generate
6
+
7
+ it 'should not error when passing a valid hash' do
8
+ id = mocker.identifier
9
+
10
+ item = CVE::Vulnerability.new({
11
+ :identifier => id,
12
+ :title => mocker.title(id),
13
+ :link => mocker.link(id),
14
+ :description => mocker.description,
15
+ :date => mocker.date
16
+ })
17
+
18
+ expect(item).to be_a(CVE::Vulnerability)
19
+ end
20
+
21
+ it 'should compare to a CVE with the same identifier and link' do
22
+ id = mocker.identifier
23
+ link = mocker.link(id)
24
+ item = CVE::Vulnerability.new({
25
+ :identifier => id,
26
+ :title => mocker.title(id),
27
+ :link => link,
28
+ :description => mocker.description,
29
+ :date => mocker.date
30
+ })
31
+
32
+ item_roughly_identical = CVE::Vulnerability.new({
33
+ :identifier => id,
34
+ :title => mocker.title(id),
35
+ :link => link,
36
+ :description => mocker.description,
37
+ :date => mocker.date
38
+ })
39
+
40
+ expect(item.equal?(item_roughly_identical, false)).to equal(true)
41
+ end
42
+
43
+ it 'should compare strictly to an identical CVE' do
44
+ id = mocker.identifier
45
+ item = CVE::Vulnerability.new({
46
+ :identifier => id,
47
+ :title => mocker.title(id),
48
+ :link => mocker.link(id),
49
+ :description => mocker.description,
50
+ :date => mocker.date
51
+ })
52
+
53
+ item_identical = item.clone
54
+
55
+ expect(item.equal?(item_identical, true)).to equal(true)
56
+ end
57
+
58
+ it 'should fail compare strictly to an unidentical CVE with the same ID' do
59
+ id = mocker.identifier
60
+ item = CVE::Vulnerability.new({
61
+ :identifier => id,
62
+ :title => mocker.title(id),
63
+ :link => mocker.link(id),
64
+ :description => mocker.description,
65
+ :date => mocker.date
66
+ })
67
+
68
+ item_unidentical = CVE::Vulnerability.new({
69
+ :identifier => id,
70
+ :title => mocker.title(id),
71
+ :link => mocker.link(id),
72
+ :description => mocker.description,
73
+ :date => mocker.date
74
+ })
75
+
76
+ expect(item.equal?(item_unidentical, true)).to equal(false)
77
+ end
78
+
79
+ it 'should fail compare to an unidentical CVE' do
80
+ id = mocker.identifier
81
+ item = CVE::Vulnerability.new({
82
+ :identifier => id,
83
+ :title => mocker.title(id),
84
+ :link => mocker.link(id),
85
+ :description => mocker.description,
86
+ :date => mocker.date
87
+ })
88
+
89
+ id = mocker.identifier
90
+ item_unidentical = CVE::Vulnerability.new({
91
+ :identifier => id,
92
+ :title => mocker.title(id),
93
+ :link => mocker.link(id),
94
+ :description => mocker.description,
95
+ :date => mocker.date
96
+ })
97
+
98
+ expect(item.equal?(item_unidentical, false)).to equal(false)
99
+ end
100
+
101
+ it 'should be able to extract a single software from the title' do
102
+ title = 'CVE-2015-123 (firefox)'
103
+ extract = cve_vul_obj.extract_software_from_title(title)
104
+
105
+ expect(extract.count).to eq(1)
106
+ expect(extract[0]).to eq('firefox')
107
+ end
108
+
109
+ it 'should be able to extract many software from the title' do
110
+ title = 'CVE-2015-123 (firefox, firefox_esr, flash)'
111
+ extract = cve_vul_obj.extract_software_from_title(title)
112
+
113
+ expect(extract.count).to eq(3)
114
+ expect(extract[0]).to eq('firefox')
115
+ expect(extract[1]).to eq('firefox_esr')
116
+ expect(extract[2]).to eq('flash')
117
+ end
118
+
119
+ it 'should return nil for affected software when not included' do
120
+ title = 'CVE-2015-123'
121
+ extract = cve_vul_obj.extract_software_from_title(title)
122
+
123
+ expect(extract).to eq(nil)
124
+ end
125
+
126
+ it 'should error when not passing a hash' do
127
+ expect{ CVE::Vulnerability.new('') }.to raise_error(RuntimeError)
128
+ end
129
+
130
+ it 'should error when passing an empty hash' do
131
+ expect{ CVE::Vulnerability.new({}) }.to raise_error(RuntimeError)
132
+ end
133
+
134
+ it 'should error when passing a hash with missing keys' do
135
+ expect{ CVE::Vulnerability.new({:identifier => 'abc', :title => 'title'}) }.to raise_error(RuntimeError)
136
+ end
137
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cve_crawler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jos Ahrens
@@ -47,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  version: '0'
48
48
  requirements: []
49
49
  rubyforge_project:
50
- rubygems_version: 2.4.5
50
+ rubygems_version: 2.2.2
51
51
  signing_key:
52
52
  specification_version: 4
53
53
  summary: CVE Crawler