cve_crawler 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d08b715392de5eb5c6a654cdfaf1ad9402cf3f3b
4
- data.tar.gz: ec204ca9f33f79223f380c701b41c869f1754113
3
+ metadata.gz: 31c7faeb4c2a75bb522bd206fc7cde12de39fee6
4
+ data.tar.gz: b0f13771e93ec38491348ef6eb0b35f537c0a843
5
5
  SHA512:
6
- metadata.gz: 3cf8e02f4afff547d1331191df92d88dd3aeb91ae577e650bc8aeb41ad1e5fcbc23c862e834c8661d3a94f7ed4d01e28a507d1578de1fe134de84c76186716ba
7
- data.tar.gz: 1c43b325124a7006e2eb5760f44f29c88a6ede065a2be765d2ab3346d60e68b22ff60a12619a3dd3635a8a2ce0d1974a6a0a82cd3b355c1adc595c3bac6b41ec
6
+ metadata.gz: 3022536ed2bf42f437d8942a883abaa9e3125fe6ce4ab85056f776488da02080f3a370d742180a5faa88f4084e3e44023d93789bd32f00decd2834742f554085
7
+ data.tar.gz: c701cf723c1eed68b70261c92f08400a5a84495445bb9936dee050a3a821f1349e744b2c28c36beebb6ee1c0bf809c90d80f02ddf503a0bd3fd0857c9006fa9d
@@ -4,7 +4,7 @@ require 'cve_crawler/cve_parser'
4
4
 
5
5
  module CVE
6
6
  VERSION_MAJOR = 0
7
- VERSION_MINOR = 2
7
+ VERSION_MINOR = 3
8
8
  VERSION_BUILD = 0
9
9
  VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}.#{VERSION_BUILD}".freeze
10
10
 
@@ -18,6 +18,8 @@ module CVE
18
18
  @parser = Parser.new(filters)
19
19
  end
20
20
 
21
+ attr_reader :crawler, :parser
22
+
21
23
  def fetch
22
24
  body = crawl.body
23
25
  parse(body)
@@ -5,7 +5,7 @@ module CVE
5
5
  @history_size = history_size
6
6
  end
7
7
 
8
- attr_reader :history_size
8
+ attr_accessor :history, :history_size
9
9
 
10
10
  def filter(contents)
11
11
  return true unless contents.is_a?(Vulnerability)
@@ -23,8 +23,8 @@ module CVE
23
23
  end
24
24
 
25
25
  def history_check_limit
26
- if @history.length >= @history_size
27
- @history.drop(1)
26
+ if @history.length > @history_size
27
+ @history = @history.drop(@history.length - @history_size)
28
28
  end
29
29
  end
30
30
 
@@ -6,7 +6,6 @@ module CVE
6
6
  class Parser
7
7
  def initialize(filters=nil)
8
8
  @filters = []
9
-
10
9
  @filters << CVE::Filter.new
11
10
 
12
11
  if filters.is_a?(Array)
@@ -18,6 +17,8 @@ module CVE
18
17
  end
19
18
  end
20
19
 
20
+ attr_reader :filters
21
+
21
22
  def parse(content)
22
23
  results = parse_rss_feed(content)
23
24
 
@@ -55,6 +55,17 @@ module CVE
55
55
  "#{@title} - #{@link}"
56
56
  end
57
57
 
58
+ def to_hash
59
+ {
60
+ :identifier => @identifier,
61
+ :title => @title,
62
+ :link => @link,
63
+ :description => @description,
64
+ :date => @date,
65
+ :affected_software => @affected_software
66
+ }
67
+ end
68
+
58
69
  def inspect
59
70
  "#<CVE::Vulnerability id=#{@identifier} affected=#{affected_count}>"
60
71
  end
data/spec/core_spec.rb ADDED
@@ -0,0 +1,61 @@
1
+ require_relative 'spec_helper'
2
+
3
+ # Not exactly what it says on the tin: Everything here is faked to simulate an environment
4
+ # where you can dynamically crawl, parse, filter and generate new vulnerabilities like the
5
+ # real RSS feed would. This simply simulates that behaviour to verify the system as a whole
6
+ # still functions. These tests failing might not necessarily represent a failure in the core
7
+ # but are more likely to represent a failure in one of the components.
8
+ describe CVE::Core do
9
+ core = CoreMock.new
10
+
11
+ it 'should fetch new results without error' do
12
+ expect{ core.fetch }.not_to raise_error
13
+ end
14
+
15
+ it 'should list new vulnerabilities when CVE::Core#fetch is called and new vulnerabilities exist' do
16
+ result = core.fetch
17
+
18
+ expect(result.count).not_to eq(0)
19
+ end
20
+
21
+ it 'should return a list of CVE::Vulnerability when vulnerabilities have been found' do
22
+ result = core.fetch
23
+
24
+ result.each do |res|
25
+ expect(res).to be_a(CVE::Vulnerability)
26
+ end
27
+ end
28
+
29
+ it 'should not list old vulnerabilities when CVE::Core#fetch is called' do
30
+ tmp_core = create_core_object
31
+
32
+ old_cves = tmp_core.fetch
33
+ new_cves = tmp_core.fetch
34
+
35
+ new_cves.each do |new|
36
+ old_cves.each do |old|
37
+ expect(new.identifier).not_to eq(old.identifier)
38
+ expect(new.equal?(old)).to eq(false)
39
+ end
40
+ end
41
+ end
42
+
43
+ it 'should append as many items to the history as were fetched' do
44
+ tmp_core = create_core_object
45
+
46
+ result = tmp_core.fetch
47
+
48
+ expect(tmp_core.parser.filters[0].history.count).to eq(result.count)
49
+ end
50
+
51
+ it 'should append new items to the history of the filter' do
52
+ tmp_core = create_core_object
53
+
54
+ tmp_core.fetch
55
+ current_history_size = tmp_core.parser.filters[0].history.count
56
+ result = tmp_core.fetch
57
+
58
+ expect(tmp_core.parser.filters[0].history.count).not_to eq(current_history_size)
59
+ expect(tmp_core.parser.filters[0].history.count).to eq(current_history_size + result.count)
60
+ end
61
+ end
data/spec/filter_spec.rb CHANGED
@@ -16,4 +16,69 @@ describe CVE::Filter do
16
16
  expect(filter.filter(VulnerabilityMock.generate)).to equal(false)
17
17
  end
18
18
  end
19
+
20
+ it 'should not exceed the history limit imposed' do
21
+ filter = CVE::Filter.new
22
+
23
+ filter_fill_history(filter, filter.history_size + 1)
24
+
25
+ expect(filter.history.count).to eq(filter.history_size)
26
+ end
27
+
28
+ it 'should not exceed the history limit customly set' do
29
+ filter = CVE::Filter.new(3)
30
+ expect(filter.history_size).to eq(3)
31
+
32
+ filter_fill_history(filter, filter.history_size + 1)
33
+
34
+ expect(filter.history.count).to eq(filter.history_size)
35
+ end
36
+
37
+ it 'should not store duplicate history entries' do
38
+ filter = CVE::Filter.new
39
+ cve = VulnerabilityMock.generate
40
+
41
+ filter.filter(cve)
42
+ filter.filter(cve)
43
+
44
+ expect(filter.history.count).to eq(1)
45
+ end
46
+
47
+ it 'should remove older history items first' do
48
+ filter = CVE::Filter.new(1)
49
+ cve = VulnerabilityMock.generate
50
+
51
+ filter.filter(cve)
52
+ filter.filter(VulnerabilityMock.generate)
53
+
54
+ expect(filter.history[0]).not_to eq(cve)
55
+ end
56
+
57
+ it 'should remove older history items first' do
58
+ filter = CVE::Filter.new(5)
59
+ batches = []
60
+ batch = []
61
+
62
+ 2.times do
63
+ 5.times do
64
+ batch << VulnerabilityMock.generate
65
+ end
66
+ batches << batch
67
+ batch = []
68
+ end
69
+
70
+ expect {
71
+ batches.each do |vulns|
72
+ vulns.each do |vuln|
73
+ raise 'Unique filtered content was determined to be filtered?' if filter.filter(vuln) == true
74
+ end
75
+ end
76
+ }.not_to raise_error
77
+
78
+ history_ok = true
79
+ 5.times do |i|
80
+ history_ok = history_ok && filter.history[i] == batches[1][i].identifier
81
+ end
82
+ expect(history_ok).to equal(true)
83
+ end
19
84
  end
data/spec/parser_spec.rb CHANGED
@@ -22,6 +22,21 @@ describe CVE::Parser do
22
22
  expect{ parser.parse('Not xml') }.to raise_error(RuntimeError)
23
23
  end
24
24
 
25
+ it 'should parse individual items' do
26
+ vulns = []
27
+
28
+ 3.times do
29
+ vulns << VulnerabilityMock.generate
30
+ end
31
+
32
+ contents = RSSMock.new(vulns)
33
+ items = parser.parse_items(contents)
34
+
35
+ 3.times do |i|
36
+ expect(items[i].equal?(vulns[i])).to eq(true)
37
+ end
38
+ end
39
+
25
40
  it 'should extract the CVE identifier from a title' do
26
41
  title = VulnerabilityMock.new.title
27
42
 
data/spec/spec_helper.rb CHANGED
@@ -1,84 +1,21 @@
1
1
  require 'rspec'
2
2
  require_relative File.join('..', 'lib', 'cve_crawler')
3
+ require_relative 'mocks/rss_mock'
4
+ require_relative 'mocks/cve_crawler_mock'
5
+ require_relative 'mocks/vulnerability_mock'
3
6
 
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)}"
7
+ def filter_fill_history(filter, size)
8
+ size.times do
9
+ filter.filter(VulnerabilityMock.generate)
64
10
  end
65
11
 
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
12
+ filter
13
+ end
74
14
 
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
15
+ def create_core_object
16
+ # Ensure a clear history and a large history buffer to avoid tests failing when the limit is reached
17
+ tmp_core = CoreMock.new
18
+ tmp_core.parser.filters[0].history_size = 50 if tmp_core.parser.filters[0].history_size < 50
80
19
 
81
- def date
82
- Time.now
83
- end
20
+ tmp_core
84
21
  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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jos Ahrens
@@ -22,6 +22,7 @@ files:
22
22
  - lib/cve_crawler/cve_filter.rb
23
23
  - lib/cve_crawler/cve_parser.rb
24
24
  - lib/cve_crawler/cve_vulnerability.rb
25
+ - spec/core_spec.rb
25
26
  - spec/crawler_spec.rb
26
27
  - spec/filter_spec.rb
27
28
  - spec/parser_spec.rb