cve_crawler 0.2.0 → 0.3.0

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: 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