dradis-netsparker 4.15.0 → 4.16.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/dradis/plugins/netsparker/gem_version.rb +1 -1
- data/lib/dradis/plugins/netsparker/importer.rb +25 -13
- data/lib/netsparker/vulnerability.rb +1 -0
- data/spec/fixtures/files/multiple-nodes.xml +56 -0
- data/spec/netsparker/importer_spec.rb +69 -0
- metadata +6 -4
- data/spec/dradis-netsparker_spec.rb +0 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e17018715e12dec6678428a291684165adf27dc5ac42f071be11bf2a9c5ec9ae
|
4
|
+
data.tar.gz: fc2a2e2f197d4d1d4c3a21ffa09def600299986bbf9d0433b286a5282985a353
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de430a263b83f423368a6fffdb560678e16b05db0a860710ee7acc6c5f6af9958b18b11ff58fee5d3985f1d964b1ea5043ba29757fdbce359beb3e4cf8cd0ded
|
7
|
+
data.tar.gz: 8c664b428f4593f77d10331dc3f12de9063e133647ef0540ee442d3a020fd4b3239ccb94a97745d55ea24ea3274c0fa1c677392b78069eb17056cedef27a66ec
|
data/CHANGELOG.md
CHANGED
@@ -7,16 +7,16 @@ module Dradis::Plugins::Netsparker
|
|
7
7
|
# The framework will call this function if the user selects this plugin from
|
8
8
|
# the dropdown list and uploads a file.
|
9
9
|
# @returns true if the operation was successful, false otherwise
|
10
|
-
def import(params={})
|
11
|
-
file_content = File.read(
|
10
|
+
def import(params = {})
|
11
|
+
file_content = File.read(params.fetch(:file))
|
12
12
|
|
13
|
-
logger.info{'Parsing Netsparker output file...'}
|
14
|
-
@doc = Nokogiri::XML(
|
15
|
-
logger.info{'Done.'}
|
13
|
+
logger.info { 'Parsing Netsparker output file...' }
|
14
|
+
@doc = Nokogiri::XML(file_content)
|
15
|
+
logger.info { 'Done.' }
|
16
16
|
|
17
17
|
if @doc.xpath('/netsparker').empty?
|
18
|
-
error =
|
19
|
-
logger.fatal{ error }
|
18
|
+
error = 'No scan results were detected in the uploaded file (/netsparker). Ensure you uploaded an Netsparker XML report.'
|
19
|
+
logger.fatal { error }
|
20
20
|
content_service.create_note text: error
|
21
21
|
return false
|
22
22
|
end
|
@@ -34,34 +34,46 @@ module Dradis::Plugins::Netsparker
|
|
34
34
|
# Create Nodes from the <url> tags
|
35
35
|
host_node_label = xml_host.at_xpath('./url').text
|
36
36
|
host_node_label = URI.parse(host_node_label).host rescue host_node_label
|
37
|
-
logger.info{ "\t\t => Creating new host: #{host_node_label}" }
|
37
|
+
logger.info { "\t\t => Creating new host: #{host_node_label}" }
|
38
38
|
host_node = content_service.create_node(label: host_node_label, type: :host)
|
39
39
|
|
40
40
|
@doc.xpath('/netsparker/vulnerability').each do |xml_vuln|
|
41
41
|
process_vuln(xml_vuln, host_node)
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
45
44
|
|
46
45
|
def process_vuln(xml_vuln, host_node)
|
47
|
-
type = xml_vuln.at_xpath('./type').text
|
46
|
+
type = xml_vuln.at_xpath('./type').text
|
48
47
|
|
49
48
|
# Create Issues using the Issue template
|
50
|
-
logger.info{ "\t\t => Creating new Issue: #{type}" }
|
49
|
+
logger.info { "\t\t => Creating new Issue: #{type}" }
|
51
50
|
|
52
51
|
issue_text = mapping_service.apply_mapping(source: 'issue', data: xml_vuln)
|
53
52
|
issue = content_service.create_issue(text: issue_text, id: type)
|
54
53
|
|
55
54
|
# Create Evidence using the Evidence template
|
56
55
|
# Associate the Evidence with the Node and Issue
|
57
|
-
logger.info{ "\t\t => Creating new evidence" }
|
56
|
+
logger.info { "\t\t => Creating new evidence" }
|
58
57
|
evidence_content = mapping_service.apply_mapping(
|
59
58
|
source: 'evidence', data: xml_vuln
|
60
59
|
)
|
60
|
+
|
61
|
+
node = get_node(xml_vuln, host_node)
|
62
|
+
|
61
63
|
content_service.create_evidence(
|
62
|
-
issue: issue, node:
|
64
|
+
issue: issue, node: node, content: evidence_content
|
63
65
|
)
|
64
66
|
end
|
65
67
|
|
68
|
+
def get_node(xml_vuln, host_node)
|
69
|
+
url = xml_vuln.at_xpath('./url').text
|
70
|
+
|
71
|
+
# If the URL is a valid URI and is not the same as the host_node, create a new node
|
72
|
+
if url =~ URI::ABS_URI && URI(url).host != host_node.label
|
73
|
+
content_service.create_node(label: URI(url).host, type: :host)
|
74
|
+
else
|
75
|
+
host_node
|
76
|
+
end
|
77
|
+
end
|
66
78
|
end
|
67
79
|
end
|
@@ -147,6 +147,7 @@ module Netsparker
|
|
147
147
|
|
148
148
|
result.gsub!(/<a .*?href=(?:\"|\')(.*?)(?:\"|\').*?>(?:<i.*?<\/i>)?(.*?)<\/a>/i) { "\"#{$2.strip}\":#{$1.strip}" }
|
149
149
|
|
150
|
+
result.gsub!(/<code>(.*?)<\/code>/) { "@#{$1}@" }
|
150
151
|
result.gsub!(/<code><pre.*?>(.*?)<\/pre><\/code>/m) {|m| "\n\nbc.. #{$1}\n\np. \n" }
|
151
152
|
result.gsub!(/<pre.*?>(.*?)<\/pre>/m) {|m| "\n\nbc.. #{$1}\n\np. \n" }
|
152
153
|
result.gsub!(/<code>(.*?)<\/code>/m) {|m| "\n\nbc.. #{$1}\n\np. \n" }
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<?xml-stylesheet href="vulnerabilities-list.xsl" type="text/xsl" ?>
|
3
|
+
|
4
|
+
<netsparker generated="1.2.2017 12:34:45">
|
5
|
+
<target>
|
6
|
+
<url>https://snorby.org/</url>
|
7
|
+
<scantime>1470</scantime>
|
8
|
+
</target>
|
9
|
+
<vulnerability confirmed="False">
|
10
|
+
<url>https://snorby.org/foo</url>
|
11
|
+
<type>EmailDisclosure</type>
|
12
|
+
<severity>Information</severity>
|
13
|
+
<certainty>95</certainty>
|
14
|
+
|
15
|
+
<rawrequest><rawrequest><![CDATA[REDACTED}]]></rawrequest></rawrequest>
|
16
|
+
<rawresponse><rawrequest><![CDATA[REDACTED}]]></rawrequest></rawresponse>
|
17
|
+
<extrainformation>
|
18
|
+
</extrainformation>
|
19
|
+
|
20
|
+
<proofs></proofs>
|
21
|
+
<classification>
|
22
|
+
<OWASP2013></OWASP2013>
|
23
|
+
<WASC>13</WASC>
|
24
|
+
<CWE>200</CWE>
|
25
|
+
<CAPEC>118</CAPEC>
|
26
|
+
<PCI31></PCI31>
|
27
|
+
<PCI32></PCI32>
|
28
|
+
<HIPAA></HIPAA>
|
29
|
+
<OWASPPC>C7</OWASPPC>
|
30
|
+
</classification>
|
31
|
+
|
32
|
+
</vulnerability>
|
33
|
+
<vulnerability confirmed="False">
|
34
|
+
<url>https://example.com</url>
|
35
|
+
<type>EmailDisclosure</type>
|
36
|
+
<severity>Information</severity>
|
37
|
+
<certainty>95</certainty>
|
38
|
+
|
39
|
+
<rawrequest><rawrequest><![CDATA[REDACTED}]]></rawrequest></rawrequest>
|
40
|
+
<rawresponse><rawrequest><![CDATA[REDACTED}]]></rawrequest></rawresponse>
|
41
|
+
<extrainformation>
|
42
|
+
<info name="Email Address(es)"><![CDATA[info@snorby.org]]></info>
|
43
|
+
</extrainformation>
|
44
|
+
<proofs></proofs>
|
45
|
+
<classification>
|
46
|
+
<OWASP2013></OWASP2013>
|
47
|
+
<WASC>13</WASC>
|
48
|
+
<CWE>200</CWE>
|
49
|
+
<CAPEC>118</CAPEC>
|
50
|
+
<PCI31></PCI31>
|
51
|
+
<PCI32></PCI32>
|
52
|
+
<HIPAA></HIPAA>
|
53
|
+
<OWASPPC>C7</OWASPPC>
|
54
|
+
</classification>
|
55
|
+
</vulnerability>
|
56
|
+
</netsparker>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
require File.expand_path('../../../../dradis-plugins/spec/support/spec_macros.rb', __FILE__)
|
5
|
+
|
6
|
+
include Dradis::Plugins::SpecMacros
|
7
|
+
|
8
|
+
module Dradis::Plugins
|
9
|
+
describe 'Netsparker upload plugin' do
|
10
|
+
before(:each) do
|
11
|
+
@fixtures_dir = File.expand_path('../../fixtures/files/', __FILE__)
|
12
|
+
|
13
|
+
stub_content_service
|
14
|
+
|
15
|
+
@importer = Dradis::Plugins::Netsparker::Importer.new(
|
16
|
+
content_service: @content_service
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'creates the expected Node, Issue, and Evidence from the example file' do
|
21
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: 'localhost', type: :host)
|
22
|
+
|
23
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
24
|
+
expect(args[:text]).to include('All sensitive data should be transferred over HTTPS rather than HTTP')
|
25
|
+
expect(args[:id]).to eq('PasswordOverHttp')
|
26
|
+
OpenStruct.new(args)
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(@content_service).to receive(:create_evidence) do |args|
|
30
|
+
expect(args[:content]).to include("#[Request]#\nbc.. GET /login HTTP/1.1")
|
31
|
+
expect(args[:issue].id).to eq('PasswordOverHttp')
|
32
|
+
expect(args[:node].label).to eq('localhost')
|
33
|
+
end
|
34
|
+
|
35
|
+
@importer.import(file: @fixtures_dir + '/example.xml')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'creates than one instance of Evidence for a single Issue' do
|
39
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: 'snorby.org', type: :host)
|
40
|
+
|
41
|
+
expect(@content_service).to receive(:create_issue) do |args|
|
42
|
+
expect(args[:text]).to include("#[Severity]#\nInformation")
|
43
|
+
expect(args[:id]).to eq('EmailDisclosure')
|
44
|
+
OpenStruct.new(args)
|
45
|
+
end
|
46
|
+
|
47
|
+
expect(@content_service).to receive(:create_evidence) do |args|
|
48
|
+
expect(args[:content]).to include("#[URL]#\nhttps://snorby.org/foo")
|
49
|
+
expect(args[:issue].id).to eq('EmailDisclosure')
|
50
|
+
expect(args[:node].label).to eq('snorby.org')
|
51
|
+
end.once
|
52
|
+
|
53
|
+
expect(@content_service).to receive(:create_evidence) do |args|
|
54
|
+
expect(args[:content]).to include("#[URL]#\nhttps://snorby.org/bar")
|
55
|
+
expect(args[:issue].id).to eq('EmailDisclosure')
|
56
|
+
expect(args[:node].label).to eq('snorby.org')
|
57
|
+
end.once
|
58
|
+
|
59
|
+
@importer.import(file: @fixtures_dir + '/example-evidence.xml')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'creates multiple nodes for additional websites' do
|
63
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: 'snorby.org', type: :host)
|
64
|
+
expect(@content_service).to receive(:create_node).with(hash_including label: 'example.com', type: :host)
|
65
|
+
|
66
|
+
@importer.import(file: @fixtures_dir + '/multiple-nodes.xml')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dradis-netsparker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dradis-plugins
|
@@ -122,11 +122,12 @@ files:
|
|
122
122
|
- lib/dradis/plugins/netsparker/version.rb
|
123
123
|
- lib/netsparker/vulnerability.rb
|
124
124
|
- lib/tasks/thorfile.rb
|
125
|
-
- spec/dradis-netsparker_spec.rb
|
126
125
|
- spec/fixtures/files/example-evidence.xml
|
127
126
|
- spec/fixtures/files/example.xml
|
127
|
+
- spec/fixtures/files/multiple-nodes.xml
|
128
128
|
- spec/fixtures/files/netsparker-localhost-demo.xml
|
129
129
|
- spec/fixtures/files/testsparker.xml
|
130
|
+
- spec/netsparker/importer_spec.rb
|
130
131
|
- spec/spec_helper.rb
|
131
132
|
- spec/vulnerability_spec.rb
|
132
133
|
- templates/evidence.sample
|
@@ -155,10 +156,11 @@ signing_key:
|
|
155
156
|
specification_version: 4
|
156
157
|
summary: Netsparker add-on for the Dradis Framework.
|
157
158
|
test_files:
|
158
|
-
- spec/dradis-netsparker_spec.rb
|
159
159
|
- spec/fixtures/files/example-evidence.xml
|
160
160
|
- spec/fixtures/files/example.xml
|
161
|
+
- spec/fixtures/files/multiple-nodes.xml
|
161
162
|
- spec/fixtures/files/netsparker-localhost-demo.xml
|
162
163
|
- spec/fixtures/files/testsparker.xml
|
164
|
+
- spec/netsparker/importer_spec.rb
|
163
165
|
- spec/spec_helper.rb
|
164
166
|
- spec/vulnerability_spec.rb
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ostruct'
|
3
|
-
|
4
|
-
module Dradis::Plugins
|
5
|
-
describe 'Netsparker upload plugin' do
|
6
|
-
before(:each) do
|
7
|
-
# Stub template service
|
8
|
-
templates_dir = File.expand_path('../../templates', __FILE__)
|
9
|
-
expect_any_instance_of(TemplateService).to \
|
10
|
-
receive(:default_templates_dir).and_return(templates_dir)
|
11
|
-
|
12
|
-
plugin = Dradis::Plugins::Netsparker
|
13
|
-
|
14
|
-
@content_service = Dradis::Plugins::ContentService::Base.new(
|
15
|
-
logger: Logger.new(STDOUT),
|
16
|
-
plugin: plugin
|
17
|
-
)
|
18
|
-
|
19
|
-
@importer = Dradis::Plugins::Netsparker::Importer.new(
|
20
|
-
content_service: @content_service
|
21
|
-
)
|
22
|
-
|
23
|
-
# Stub dradis-plugins methods
|
24
|
-
#
|
25
|
-
# They return their argument hashes as objects mimicking
|
26
|
-
# Nodes, Issues, etc
|
27
|
-
allow(@content_service).to receive(:create_node) do |args|
|
28
|
-
OpenStruct.new(args)
|
29
|
-
end
|
30
|
-
allow(@content_service).to receive(:create_note) do |args|
|
31
|
-
OpenStruct.new(args)
|
32
|
-
end
|
33
|
-
allow(@content_service).to receive(:create_issue) do |args|
|
34
|
-
OpenStruct.new(args)
|
35
|
-
end
|
36
|
-
allow(@content_service).to receive(:create_evidence) do |args|
|
37
|
-
OpenStruct.new(args)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it "creates the expected Node, Issue, and Evidence from the example file" do
|
42
|
-
expect(@content_service).to receive(:create_node).with(hash_including label: 'localhost', type: :host)
|
43
|
-
|
44
|
-
expect(@content_service).to receive(:create_issue) do |args|
|
45
|
-
expect(args[:text]).to include("#[Title]#\nPassword over http")
|
46
|
-
expect(args[:id]).to eq("PasswordOverHttp")
|
47
|
-
OpenStruct.new(args)
|
48
|
-
end
|
49
|
-
|
50
|
-
expect(@content_service).to receive(:create_evidence) do |args|
|
51
|
-
expect(args[:content]).to include("#[Request]#\nbc.. GET /login HTTP/1.1")
|
52
|
-
expect(args[:issue].id).to eq("PasswordOverHttp")
|
53
|
-
expect(args[:node].label).to eq("localhost")
|
54
|
-
end
|
55
|
-
|
56
|
-
@importer.import(file: 'spec/fixtures/files/example.xml')
|
57
|
-
end
|
58
|
-
|
59
|
-
it "creates than one instance of Evidence for a single Issue" do
|
60
|
-
expect(@content_service).to receive(:create_node).with(hash_including label: 'snorby.org', type: :host)
|
61
|
-
|
62
|
-
expect(@content_service).to receive(:create_issue) do |args|
|
63
|
-
expect(args[:text]).to include("#[Title]#\nEmail disclosure")
|
64
|
-
expect(args[:id]).to eq("EmailDisclosure")
|
65
|
-
OpenStruct.new(args)
|
66
|
-
end
|
67
|
-
|
68
|
-
expect(@content_service).to receive(:create_evidence) do |args|
|
69
|
-
expect(args[:content]).to include("#[URL]#\nhttps://snorby.org/foo")
|
70
|
-
expect(args[:issue].id).to eq("EmailDisclosure")
|
71
|
-
expect(args[:node].label).to eq("snorby.org")
|
72
|
-
end.once
|
73
|
-
|
74
|
-
expect(@content_service).to receive(:create_evidence) do |args|
|
75
|
-
expect(args[:content]).to include("#[URL]#\nhttps://snorby.org/bar")
|
76
|
-
expect(args[:issue].id).to eq("EmailDisclosure")
|
77
|
-
expect(args[:node].label).to eq("snorby.org")
|
78
|
-
end.once
|
79
|
-
|
80
|
-
@importer.import(file: 'spec/fixtures/files/example-evidence.xml')
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|