spektr 0.1.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +11 -7
- data/README.md +18 -3
- data/lib/spektr/app.rb +7 -3
- data/lib/spektr/cli.rb +7 -1
- data/lib/spektr/targets/view.rb +4 -1
- data/lib/spektr/version.rb +1 -1
- data/lib/spektr/warning.rb +8 -3
- data/lib/spektr.rb +28 -17
- data/railsgoat-example.png +0 -0
- data/spektr.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a10d35b4824401e5731ad470bbdc042ee63a11e9df5abd1eec5552005e44f25f
|
|
4
|
+
data.tar.gz: 28859b54116afb3847fcc96a32260aa00f8deb3d02135149a219d14fe58f4261
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a78047b2e601f90fe6008ebfb2ea0c440e4168ee9493fcd5f6ad83108a752fabfec9f957d0892b302565a0549220179e3a796dc9bc0fd7ab35ccfd9db61bffd9
|
|
7
|
+
data.tar.gz: fdc98737aed0b3fcc042cb745b6093d2a17790705932096df952ff48e8eea714275f57a3a9f9313d60e5fb5fc4798da23e5af8695e5e914c7aa08c79cc5074a4
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
spektr (0.
|
|
4
|
+
spektr (0.3.0)
|
|
5
5
|
activesupport (~> 6.1.0)
|
|
6
6
|
erubi
|
|
7
7
|
haml (~> 5.1)
|
|
8
8
|
parser (~> 3.0.0)
|
|
9
9
|
pastel
|
|
10
10
|
ruby_parser (~> 3.13)
|
|
11
|
+
slim
|
|
11
12
|
tty-color
|
|
12
13
|
tty-option
|
|
13
14
|
tty-spinner
|
|
@@ -18,7 +19,7 @@ PATH
|
|
|
18
19
|
GEM
|
|
19
20
|
remote: https://rubygems.org/
|
|
20
21
|
specs:
|
|
21
|
-
activesupport (6.1.
|
|
22
|
+
activesupport (6.1.7)
|
|
22
23
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
23
24
|
i18n (>= 1.6, < 2)
|
|
24
25
|
minitest (>= 5.1)
|
|
@@ -29,7 +30,7 @@ GEM
|
|
|
29
30
|
coderay (1.1.3)
|
|
30
31
|
concurrent-ruby (1.1.10)
|
|
31
32
|
diff-lcs (1.5.0)
|
|
32
|
-
erubi (1.
|
|
33
|
+
erubi (1.11.0)
|
|
33
34
|
ffi (1.15.5)
|
|
34
35
|
formatador (0.3.0)
|
|
35
36
|
guard (2.18.0)
|
|
@@ -48,7 +49,7 @@ GEM
|
|
|
48
49
|
haml (5.2.2)
|
|
49
50
|
temple (>= 0.8.0)
|
|
50
51
|
tilt
|
|
51
|
-
i18n (1.
|
|
52
|
+
i18n (1.12.0)
|
|
52
53
|
concurrent-ruby (~> 1.0)
|
|
53
54
|
listen (3.7.1)
|
|
54
55
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
@@ -91,6 +92,9 @@ GEM
|
|
|
91
92
|
sexp_processor (~> 4.16)
|
|
92
93
|
sexp_processor (4.16.1)
|
|
93
94
|
shellany (0.0.1)
|
|
95
|
+
slim (4.1.0)
|
|
96
|
+
temple (>= 0.7.6, < 0.9)
|
|
97
|
+
tilt (>= 2.0.6, < 2.1)
|
|
94
98
|
strings (0.2.1)
|
|
95
99
|
strings-ansi (~> 0.2)
|
|
96
100
|
unicode-display_width (>= 1.5, < 3.0)
|
|
@@ -98,7 +102,7 @@ GEM
|
|
|
98
102
|
strings-ansi (0.2.0)
|
|
99
103
|
temple (0.8.2)
|
|
100
104
|
thor (1.2.1)
|
|
101
|
-
tilt (2.0.
|
|
105
|
+
tilt (2.0.11)
|
|
102
106
|
tty-color (0.6.0)
|
|
103
107
|
tty-cursor (0.7.1)
|
|
104
108
|
tty-option (0.2.0)
|
|
@@ -109,14 +113,14 @@ GEM
|
|
|
109
113
|
pastel (~> 0.8)
|
|
110
114
|
strings (~> 0.2.0)
|
|
111
115
|
tty-screen (~> 0.8)
|
|
112
|
-
tzinfo (2.0.
|
|
116
|
+
tzinfo (2.0.5)
|
|
113
117
|
concurrent-ruby (~> 1.0)
|
|
114
118
|
unicode-display_width (2.1.0)
|
|
115
119
|
unicode_utils (1.4.0)
|
|
116
120
|
unparser (0.6.2)
|
|
117
121
|
diff-lcs (~> 1.3)
|
|
118
122
|
parser (>= 3.0.0)
|
|
119
|
-
zeitwerk (2.6.
|
|
123
|
+
zeitwerk (2.6.1)
|
|
120
124
|
|
|
121
125
|
PLATFORMS
|
|
122
126
|
ruby
|
data/README.md
CHANGED
|
@@ -34,6 +34,20 @@ If you want to scan an app in another folder:
|
|
|
34
34
|
spektr path/to/app
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
To see the available options, you can run `spektr --help`.
|
|
38
|
+
|
|
39
|
+
To ignore a finding, you can use the `--ignore` flag with a comma separated list of fingerprints from the report.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Railsgoat Example output
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
### False positives
|
|
47
|
+
|
|
48
|
+
Due to the nature of static-code analysis, Spektr might report false positives. Please report them, so I can try
|
|
49
|
+
to tweak the check.
|
|
50
|
+
|
|
37
51
|
|
|
38
52
|
## Development
|
|
39
53
|
|
|
@@ -43,12 +57,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
43
57
|
|
|
44
58
|
## Contributing
|
|
45
59
|
|
|
46
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
|
60
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gregmolnar/spektr. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/gregmolnar/spektr/blob/master/CODE_OF_CONDUCT.md).
|
|
47
61
|
|
|
48
62
|
|
|
49
63
|
## License
|
|
50
64
|
|
|
51
|
-
The gem is available as open source under the terms described in the [licence](https://github.com/gregmolnar/spektr/blob/master/
|
|
65
|
+
The gem is available as open source under the terms described in the [licence](https://github.com/gregmolnar/spektr/blob/master/LICENSE.txt). Non-commercial use is free of charge, to obtain a commercial licence, contact us at info[at]spektrhq.com.
|
|
66
|
+
If you are looking for a hosted solution, take a look at [SpektrHQ](https://spektrhq.com).
|
|
52
67
|
|
|
53
68
|
|
|
54
69
|
## Code of Conduct
|
|
@@ -63,7 +78,7 @@ Yes, this is perfectly fine without obtaining a licence. You can however donate
|
|
|
63
78
|
|
|
64
79
|
### I want to use Spektr in my automated code analyser SaaS, do I need a commercial licence?
|
|
65
80
|
|
|
66
|
-
Yes,
|
|
81
|
+
Yes, please get in touch at info[at]spektrhq.com and we will work something out.
|
|
67
82
|
|
|
68
83
|
### I am a penetration tester and I'd like to use Spektr to audit on a paid engagement. Do I need a commercial licence?
|
|
69
84
|
|
data/lib/spektr/app.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Spektr
|
|
|
7
7
|
@@parser ||= Parser::CurrentRuby
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def initialize(checks:, root: './')
|
|
10
|
+
def initialize(checks:, ignore:, root: './')
|
|
11
11
|
@root = root
|
|
12
12
|
@checks = checks
|
|
13
13
|
@controllers = []
|
|
@@ -17,6 +17,7 @@ module Spektr
|
|
|
17
17
|
app: {},
|
|
18
18
|
advisories: []
|
|
19
19
|
}
|
|
20
|
+
@ignore = ignore || []
|
|
20
21
|
@ruby_version = '2.7.1'
|
|
21
22
|
version_file = File.join(root, '.ruby-version')
|
|
22
23
|
@ruby_version = File.read(version_file).lines.first if File.exist?(version_file)
|
|
@@ -137,7 +138,7 @@ module Spektr
|
|
|
137
138
|
self
|
|
138
139
|
end
|
|
139
140
|
|
|
140
|
-
def report
|
|
141
|
+
def report
|
|
141
142
|
@json_output[:app][:rails_version] = @rails_version
|
|
142
143
|
@json_output[:app][:initializers] = @initializers.size
|
|
143
144
|
@json_output[:app][:controllers] = @controllers.size
|
|
@@ -147,13 +148,16 @@ module Spektr
|
|
|
147
148
|
@json_output[:app][:lib_files] = @lib_files.size
|
|
148
149
|
|
|
149
150
|
@warnings.each do |warning|
|
|
151
|
+
next if @ignore.include?(warning.fingerprint)
|
|
152
|
+
|
|
150
153
|
@json_output[:advisories] << {
|
|
151
154
|
name: warning.check.name,
|
|
152
155
|
description: warning.message,
|
|
153
156
|
path: warning.path,
|
|
154
157
|
location: warning.location&.line,
|
|
155
158
|
line: warning.line,
|
|
156
|
-
check: warning.check.class.name
|
|
159
|
+
check: warning.check.class.name,
|
|
160
|
+
fingerprint: warning.fingerprint
|
|
157
161
|
}
|
|
158
162
|
end
|
|
159
163
|
|
data/lib/spektr/cli.rb
CHANGED
|
@@ -25,6 +25,11 @@ module Spektr
|
|
|
25
25
|
desc 'run this single check'
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
flag :ignore do
|
|
29
|
+
long '--ignore string'
|
|
30
|
+
desc 'comma separated list of fingerprints to ignore'
|
|
31
|
+
end
|
|
32
|
+
|
|
28
33
|
flag :debug do
|
|
29
34
|
long '--debug'
|
|
30
35
|
short '-d'
|
|
@@ -42,7 +47,8 @@ module Spektr
|
|
|
42
47
|
print help
|
|
43
48
|
exit
|
|
44
49
|
else
|
|
45
|
-
|
|
50
|
+
ignore = params[:ignore] ? params[:ignore].split(',') : []
|
|
51
|
+
report = Spektr.run(params[:root], params[:output_format], params[:debug], params[:check], ignore)
|
|
46
52
|
case params[:output_format]
|
|
47
53
|
when 'json'
|
|
48
54
|
puts JSON.pretty_generate report
|
data/lib/spektr/targets/view.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Spektr
|
|
2
2
|
module Targets
|
|
3
3
|
class View < Base
|
|
4
|
-
TEMPLATE_EXTENSIONS = /.*\.(erb|rhtml|haml)$/
|
|
4
|
+
TEMPLATE_EXTENSIONS = /.*\.(erb|rhtml|haml|slim)$/
|
|
5
5
|
attr_accessor :view_path
|
|
6
6
|
|
|
7
7
|
def initialize(path, content)
|
|
@@ -27,6 +27,9 @@ module Spektr
|
|
|
27
27
|
Erubi.new(content, trim_mode: '-').src
|
|
28
28
|
when :haml
|
|
29
29
|
Haml::Engine.new(content).precompiled
|
|
30
|
+
when :slim
|
|
31
|
+
erb = Slim::ERBConverter.new.call(content)
|
|
32
|
+
Erubi.new(erb, trim_mode: '-').src
|
|
30
33
|
end
|
|
31
34
|
end
|
|
32
35
|
end
|
data/lib/spektr/version.rb
CHANGED
data/lib/spektr/warning.rb
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
|
|
1
3
|
module Spektr
|
|
2
4
|
class Warning
|
|
3
5
|
attr_accessor :path, :full_path, :check, :location, :message, :confidence, :line
|
|
6
|
+
|
|
4
7
|
def initialize(path, full_path, check, location, message, confidence = :high)
|
|
5
8
|
@path = path
|
|
6
9
|
@check = check
|
|
7
10
|
@location = location
|
|
8
11
|
@message = message
|
|
9
12
|
@confidence = confidence
|
|
10
|
-
if full_path && @location && File.exist?(full_path)
|
|
11
|
-
@line = IO.readlines(full_path)[@location.line - 1].strip
|
|
12
|
-
end
|
|
13
|
+
@line = IO.readlines(full_path)[@location.line - 1].strip if full_path && @location && File.exist?(full_path)
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def full_message
|
|
@@ -19,5 +20,9 @@ module Spektr
|
|
|
19
20
|
"#{message}"
|
|
20
21
|
end
|
|
21
22
|
end
|
|
23
|
+
|
|
24
|
+
def fingerprint
|
|
25
|
+
Digest::MD5.hexdigest("#{path}:#{line}:#{check.name}")
|
|
26
|
+
end
|
|
22
27
|
end
|
|
23
28
|
end
|
data/lib/spektr.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'bundler'
|
|
3
4
|
require 'parser'
|
|
4
5
|
require 'parser/current'
|
|
5
6
|
require 'unparser'
|
|
6
7
|
require 'erb'
|
|
8
|
+
require 'slim/erb_converter'
|
|
7
9
|
require 'haml'
|
|
8
10
|
require 'active_support/core_ext/string/inflections'
|
|
9
11
|
require 'logger'
|
|
@@ -13,33 +15,37 @@ require 'tty/table'
|
|
|
13
15
|
require 'zeitwerk'
|
|
14
16
|
loader = Zeitwerk::Loader.for_gem
|
|
15
17
|
loader.collapse("#{__dir__}/processors")
|
|
16
|
-
loader.setup
|
|
17
|
-
loader.eager_load
|
|
18
|
+
loader.setup
|
|
18
19
|
|
|
19
20
|
module Spektr
|
|
20
21
|
class Error < StandardError; end
|
|
21
22
|
|
|
22
|
-
def self.run(root = nil, output_format = 'terminal', debug = false, checks = nil)
|
|
23
|
+
def self.run(root = nil, output_format = 'terminal', debug = false, checks = nil, ignore = [])
|
|
23
24
|
pastel = Pastel.new
|
|
24
25
|
@output_format = output_format
|
|
25
26
|
start_spinner('Initializing')
|
|
26
|
-
|
|
27
|
+
if debug
|
|
28
|
+
Logger::DEBUG
|
|
29
|
+
elsif terminal?
|
|
30
|
+
Logger::ERROR
|
|
31
|
+
else
|
|
32
|
+
Logger::WARN
|
|
33
|
+
end
|
|
27
34
|
checks = Checks.load(checks)
|
|
28
35
|
root = './' if root.nil?
|
|
29
|
-
@app = App.new(checks: checks, root: root)
|
|
36
|
+
@app = App.new(checks: checks, root: root, ignore: ignore)
|
|
30
37
|
stop_spinner
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
if terminal?
|
|
39
|
+
puts "\n"
|
|
40
|
+
puts pastel.bold('Checks:')
|
|
41
|
+
puts "\n"
|
|
42
|
+
puts checks.collect(&:name).join(', ')
|
|
43
|
+
puts "\n"
|
|
44
|
+
end
|
|
38
45
|
|
|
39
46
|
start_spinner('Loading files')
|
|
40
47
|
@app.load
|
|
41
48
|
stop_spinner
|
|
42
|
-
puts "\n"
|
|
43
49
|
table = TTY::Table.new([
|
|
44
50
|
['Rails version', @app.rails_version],
|
|
45
51
|
['Initializers', @app.initializers.size],
|
|
@@ -49,13 +55,17 @@ module Spektr
|
|
|
49
55
|
['Routes', @app.routes.size],
|
|
50
56
|
['Lib files', @app.lib_files.size]
|
|
51
57
|
])
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
if terminal?
|
|
59
|
+
puts "\n"
|
|
60
|
+
puts table.render(:basic)
|
|
61
|
+
puts "\n"
|
|
62
|
+
end
|
|
54
63
|
start_spinner('Scanning files')
|
|
55
64
|
@app.scan!
|
|
56
65
|
stop_spinner
|
|
57
66
|
puts "\n"
|
|
58
67
|
json = @app.report
|
|
68
|
+
|
|
59
69
|
case output_format
|
|
60
70
|
when 'json'
|
|
61
71
|
json
|
|
@@ -69,6 +79,7 @@ module Spektr
|
|
|
69
79
|
puts "#{pastel.green('Path:')} #{advisory[:path]}\n"
|
|
70
80
|
puts "#{pastel.green('Location:')} #{advisory[:location]}\n"
|
|
71
81
|
puts "#{pastel.green('Code:')} #{advisory[:line]}\n"
|
|
82
|
+
puts "#{pastel.green('Fingerprint:')} #{advisory[:fingerprint]}\n"
|
|
72
83
|
puts "\n"
|
|
73
84
|
puts "\n"
|
|
74
85
|
end
|
|
@@ -112,7 +123,7 @@ module Spektr
|
|
|
112
123
|
|
|
113
124
|
def self.logger
|
|
114
125
|
@logger ||= begin
|
|
115
|
-
logger = Logger.new(
|
|
126
|
+
logger = Logger.new($stdout)
|
|
116
127
|
logger.level = @log_level || Logger::WARN
|
|
117
128
|
logger
|
|
118
129
|
end
|
|
Binary file
|
data/spektr.gemspec
CHANGED
|
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
|
|
|
33
33
|
spec.add_dependency 'parser', '~> 3.0.0'
|
|
34
34
|
spec.add_dependency 'pastel'
|
|
35
35
|
spec.add_dependency 'ruby_parser', '~>3.13'
|
|
36
|
+
spec.add_dependency 'slim'
|
|
36
37
|
spec.add_dependency 'tty-color'
|
|
37
38
|
spec.add_dependency 'tty-option'
|
|
38
39
|
spec.add_dependency 'tty-spinner'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spektr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Greg Molnar
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-10-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -94,6 +94,20 @@ dependencies:
|
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '3.13'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: slim
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
112
|
name: tty-color
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -334,6 +348,7 @@ files:
|
|
|
334
348
|
- lib/spektr/targets/view.rb
|
|
335
349
|
- lib/spektr/version.rb
|
|
336
350
|
- lib/spektr/warning.rb
|
|
351
|
+
- railsgoat-example.png
|
|
337
352
|
- spektr.gemspec
|
|
338
353
|
homepage: https://railscop.com
|
|
339
354
|
licenses:
|