cobalt-rubocop 0.1.0 → 0.5.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 +17 -1
- data/README.md +63 -15
- data/config/default.yml +4 -0
- data/config/rspec.yml +1 -0
- data/lib/rubocop/cobalt/version.rb +7 -0
- data/lib/rubocop/cop/cobalt/insecure_hash_algorithm.rb +123 -0
- data/lib/rubocop/cop/cobalt.rb +3 -0
- metadata +30 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6dc98fd50cb09459ed2b1549f9946ee1d0e73ad7be7c099b22c1ca78641cabc
|
4
|
+
data.tar.gz: bb451d97a1ef101b4a80c4d9bb66e46fed55b1b5f55a07d42f9c063c78f46139
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 864612e1bc4558bae753049b59b41387b74a7a8c83bd605b319da05f30f8c1661b984a3bd5e3305840a8eb67e3605f336960f9f4815d8d6cb5e02de48a6c68ba
|
7
|
+
data.tar.gz: d3c100cf002c07b94aa64f4603b342f1351abdb6cd4e46a4b37e640a82bea26a7b9cd8854ef956179d0e811a54589ab39dd011b0d062cef54fecfbd959f47a6a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
-
#
|
1
|
+
# CHANGELOG
|
2
|
+
## main (unreleased)
|
3
|
+
* WIP
|
2
4
|
|
5
|
+
## 0.5.0 (2022-01-25)
|
6
|
+
* Update Gem versions ([#8](https://github.com/cobalthq/cobalt-rubocop/pull/8))
|
7
|
+
|
8
|
+
## 0.4.0 (2021-09-07)
|
9
|
+
* Update Gem versions ([#7](https://github.com/cobalthq/cobalt-rubocop/pull/7))
|
10
|
+
|
11
|
+
## 0.3.0 (2021-04-16)
|
12
|
+
* Update Rubocop and Rubocop Performance versions ([#6](https://github.com/cobalthq/cobalt-rubocop/pull/6))
|
13
|
+
|
14
|
+
## 0.2.0 (2021-04-14)
|
15
|
+
* Avoid warnings on RSpec `let` with parameter arrays ([#5](https://github.com/cobalthq/cobalt-rubocop/pull/5))
|
16
|
+
* Add new cop `InsecureHashAlgorithm`. ([#3](https://github.com/cobalthq/cobalt-rubocop/pull/3))
|
17
|
+
|
18
|
+
## 0.1.0 (2021-02-10)
|
3
19
|
* Introduce default rules
|
4
20
|
* Introduce rails rules
|
5
21
|
* Introduce rspec rules
|
data/README.md
CHANGED
@@ -1,19 +1,37 @@
|
|
1
1
|
# Cobalt RuboCop
|
2
|
+
[](https://badge.fury.io/rb/cobalt-rubocop)
|
3
|
+
[](https://github.com/cobalthq/cobalt-rubocop/blob/main/LICENSE)
|
4
|
+

|
5
|
+
[](https://github.com/rubocop-hq/rubocop)
|
2
6
|
|
3
7
|
This repository provides recommended linting rules for Ruby repositories.
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
7
11
|
### Gemfile
|
12
|
+
#### Add
|
13
|
+
```ruby
|
14
|
+
group :development do
|
15
|
+
gem 'cobalt-rubocop', require: false
|
16
|
+
end
|
17
|
+
```
|
8
18
|
|
9
|
-
|
10
|
-
|
11
|
-
gem '
|
12
|
-
|
13
|
-
|
19
|
+
#### Remove
|
20
|
+
```ruby
|
21
|
+
gem 'rubocop', require: false
|
22
|
+
gem 'rubocop-performance', require: false
|
23
|
+
gem 'rubocop-rails', require: false
|
24
|
+
gem 'rubocop-rspec', require: false
|
25
|
+
```
|
14
26
|
|
15
|
-
|
27
|
+
[Specific versions](https://github.com/cobalthq/cobalt-rubocop/blob/main/cobalt-rubocop.gemspec) installed for:
|
28
|
+
- [rubocop](https://github.com/rubocop-hq/rubocop)
|
29
|
+
- [rubocop-performance](https://github.com/rubocop/rubocop-performance)
|
30
|
+
- [rubocop-rails](https://github.com/rubocop/rubocop-rails)
|
31
|
+
- [rubocop-rspec](https://github.com/rubocop/rubocop-rspec)
|
16
32
|
|
33
|
+
### .rubocop.yml
|
34
|
+
Configuration Options:
|
17
35
|
```yaml
|
18
36
|
inherit_gem:
|
19
37
|
cobalt-rubocop:
|
@@ -41,11 +59,37 @@ The number of offences can be counted:
|
|
41
59
|
grep "Offense count" .rubocop_todo.yml | awk -F: '{sum+=$2} END {print sum}'
|
42
60
|
```
|
43
61
|
|
62
|
+
## Custom Cops
|
63
|
+
### InsecureHashAlgorithm
|
64
|
+
See [Ruby Docs](https://ruby-doc.org/stdlib-2.7.2/libdoc/openssl/rdoc/OpenSSL/Digest.html) for built in hash functions.
|
65
|
+
|
66
|
+
- Default Configuration:
|
67
|
+
```yml
|
68
|
+
Cobalt/InsecureHashAlgorithm:
|
69
|
+
Allowed:
|
70
|
+
- SHA256
|
71
|
+
- SHA384
|
72
|
+
- SHA512
|
73
|
+
```
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# bad
|
77
|
+
OpenSSL::Digest::MD5.digest('abc')
|
78
|
+
OpenSSL::Digest::SHA1.digest('abc')
|
79
|
+
OpenSSL::HMAC.new('abc', 'sha1')
|
80
|
+
|
81
|
+
# good
|
82
|
+
OpenSSL::Digest::SHA256.digest('abc')
|
83
|
+
OpenSSL::Digest::SHA384.digest('abc')
|
84
|
+
OpenSSL::Digest::SHA512.digest('abc')
|
85
|
+
OpenSSL::HMAC.new('abc', 'sha256')
|
86
|
+
```
|
87
|
+
|
44
88
|
## Development
|
45
89
|
```shell
|
46
90
|
git clone git@github.com:cobalthq/cobalt-rubocop.git
|
47
|
-
gem install bundler:2.2.
|
48
|
-
bundle _2.2.
|
91
|
+
gem install bundler:2.2.16
|
92
|
+
bundle _2.2.16_
|
49
93
|
```
|
50
94
|
|
51
95
|
### Testing locally
|
@@ -55,10 +99,14 @@ In your application, use the `path` attribute to point to your local copy of the
|
|
55
99
|
gem 'cobalt-rubocop', path: '../cobalt-rubocop', require: false
|
56
100
|
```
|
57
101
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
gem
|
64
|
-
|
102
|
+
Alternatively:
|
103
|
+
- `rake build`
|
104
|
+
- `gem install pkg/cobalt-rubocop-<version_number>.gem`
|
105
|
+
|
106
|
+
## Publish (internal)
|
107
|
+
> Note: Publishing a new version of this gem is only meant for maintainers.
|
108
|
+
- Ensure you have access to publish on [rubygems](https://rubygems.org/gems/cobalt-rubocop).
|
109
|
+
- Update [CHANGELOG](https://github.com/cobalthq/cobalt-rubocop/blob/main/CHANGELOG.md).
|
110
|
+
- Update [`VERSION`](https://github.com/cobalthq/cobalt-rubocop/blob/main/lib/rubocop/cobalt/version.rb).
|
111
|
+
- `rake release`
|
112
|
+
- This command builds the gem, creates a tag and publishes to rubygems, see [bundler docs](https://bundler.io/guides/creating_gem.html#releasing-the-gem).
|
data/config/default.yml
CHANGED
data/config/rspec.yml
CHANGED
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# original code from https://github.com/github/rubocop-github/blob/master/lib/rubocop/cop/github/insecure_hash_algorithm.rb
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Cobalt
|
8
|
+
class InsecureHashAlgorithm < Cop
|
9
|
+
# Matches constants like these:
|
10
|
+
# Digest::MD5
|
11
|
+
# OpenSSL::Digest::MD5
|
12
|
+
def_node_matcher :insecure_const?, <<-PATTERN
|
13
|
+
(const (const _ :Digest) #insecure_algorithm?)
|
14
|
+
PATTERN
|
15
|
+
|
16
|
+
# Matches calls like these:
|
17
|
+
# Digest.new('md5')
|
18
|
+
# Digest.hexdigest('md5', 'str')
|
19
|
+
# OpenSSL::Digest.new('md5')
|
20
|
+
# OpenSSL::Digest.hexdigest('md5', 'str')
|
21
|
+
# OpenSSL::Digest::Digest.new('md5')
|
22
|
+
# OpenSSL::Digest::Digest.hexdigest('md5', 'str')
|
23
|
+
# OpenSSL::Digest::Digest.new(:MD5)
|
24
|
+
# OpenSSL::Digest::Digest.hexdigest(:MD5, 'str')
|
25
|
+
def_node_matcher :insecure_digest?, <<-PATTERN
|
26
|
+
(send
|
27
|
+
(const _ {:Digest :HMAC})
|
28
|
+
#not_just_encoding?
|
29
|
+
#insecure_algorithm?
|
30
|
+
...)
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
# Matches calls like "Digest(:MD5)".
|
34
|
+
def_node_matcher :insecure_hash_lookup?, <<-PATTERN
|
35
|
+
(send _ :Digest #insecure_algorithm?)
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
# Matches calls like "OpenSSL::HMAC.new(secret, hash)"
|
39
|
+
def_node_matcher :openssl_hmac_new?, <<-PATTERN
|
40
|
+
(send (const (const _ :OpenSSL) :HMAC) :new ...)
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
# Matches calls like "OpenSSL::HMAC.new(secret, 'sha1')"
|
44
|
+
def_node_matcher :openssl_hmac_new_insecure?, <<-PATTERN
|
45
|
+
(send (const (const _ :OpenSSL) :HMAC) :new _ #insecure_algorithm?)
|
46
|
+
PATTERN
|
47
|
+
|
48
|
+
# Matches Rails's Digest::UUID.
|
49
|
+
def_node_matcher :digest_uuid?, <<-PATTERN
|
50
|
+
(const (const _ :Digest) :UUID)
|
51
|
+
PATTERN
|
52
|
+
|
53
|
+
def_node_matcher :uuid_v3?, <<-PATTERN
|
54
|
+
(send (const _ :UUID) :uuid_v3 ...)
|
55
|
+
PATTERN
|
56
|
+
|
57
|
+
def_node_matcher :uuid_v5?, <<-PATTERN
|
58
|
+
(send (const _ :UUID) :uuid_v5 ...)
|
59
|
+
PATTERN
|
60
|
+
|
61
|
+
def insecure_algorithm?(val)
|
62
|
+
return false if val == :Digest # Don't match "Digest::Digest".
|
63
|
+
|
64
|
+
case alg_name(val)
|
65
|
+
when *allowed_hash_functions, Symbol
|
66
|
+
false
|
67
|
+
else
|
68
|
+
true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def not_just_encoding?(val)
|
73
|
+
!just_encoding?(val)
|
74
|
+
end
|
75
|
+
|
76
|
+
def just_encoding?(val)
|
77
|
+
%i[hexencode bubblebabble].include?(val)
|
78
|
+
end
|
79
|
+
|
80
|
+
DEFAULT_ALLOWED = %w[
|
81
|
+
SHA256
|
82
|
+
SHA384
|
83
|
+
SHA512
|
84
|
+
].freeze
|
85
|
+
|
86
|
+
def allowed_hash_functions
|
87
|
+
@allowed_hash_functions ||= cop_config.fetch('Allowed', DEFAULT_ALLOWED).map(&:downcase)
|
88
|
+
end
|
89
|
+
|
90
|
+
def alg_name(val)
|
91
|
+
return :nil if val.nil?
|
92
|
+
return val.to_s.downcase unless val.is_a?(RuboCop::AST::Node)
|
93
|
+
|
94
|
+
case val.type
|
95
|
+
when :sym, :str
|
96
|
+
val.children.first.to_s.downcase
|
97
|
+
else
|
98
|
+
val.type
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def on_const(const_node)
|
103
|
+
add_offense(const_node, message: default_message) if insecure_const?(const_node) && !digest_uuid?(const_node)
|
104
|
+
end
|
105
|
+
|
106
|
+
def on_send(send_node)
|
107
|
+
if uuid_v3?(send_node) && !allowed_hash_functions.include?('md5')
|
108
|
+
add_offense(send_node, message: "uuid_v3 uses MD5, which is not allowed. Prefer: #{allowed_hash_functions.join(', ')}")
|
109
|
+
elsif uuid_v5?(send_node) && !allowed_hash_functions.include?('sha1')
|
110
|
+
add_offense(send_node, message: "uuid_v5 uses SHA1, which is not allowed. Prefer: #{allowed_hash_functions.join(', ')}")
|
111
|
+
elsif openssl_hmac_new?(send_node) && openssl_hmac_new_insecure?(send_node) ||
|
112
|
+
insecure_digest?(send_node) || insecure_hash_lookup?(send_node)
|
113
|
+
add_offense(send_node, message: default_message)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def default_message
|
118
|
+
"This hash function is not allowed. Prefer: #{allowed_hash_functions.join(', ')}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cobalt-rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cobalt Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,70 +16,84 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.25.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.25.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubocop-performance
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.13.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.13.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rubocop-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.
|
47
|
+
version: 2.13.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.
|
54
|
+
version: 2.13.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubocop-rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.
|
61
|
+
version: 2.8.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 2.
|
68
|
+
version: 2.8.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - '='
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 2.2.
|
75
|
+
version: 2.2.16
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - '='
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.2.
|
82
|
+
version: 2.2.16
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.10.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 3.10.0
|
83
97
|
description: Ruby code linting for Cobalt Ruby repositories
|
84
98
|
email:
|
85
99
|
executables: []
|
@@ -92,6 +106,9 @@ files:
|
|
92
106
|
- config/default.yml
|
93
107
|
- config/rails.yml
|
94
108
|
- config/rspec.yml
|
109
|
+
- lib/rubocop/cobalt/version.rb
|
110
|
+
- lib/rubocop/cop/cobalt.rb
|
111
|
+
- lib/rubocop/cop/cobalt/insecure_hash_algorithm.rb
|
95
112
|
homepage: https://github.com/cobalthq/cobalt-rubocop
|
96
113
|
licenses:
|
97
114
|
- MIT
|
@@ -115,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
132
|
- !ruby/object:Gem::Version
|
116
133
|
version: '0'
|
117
134
|
requirements: []
|
118
|
-
rubygems_version: 3.
|
135
|
+
rubygems_version: 3.2.3
|
119
136
|
signing_key:
|
120
137
|
specification_version: 4
|
121
138
|
summary: Cobalt RuboCop
|