cobalt-rubocop 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +61 -13
- 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.rb +3 -0
- data/lib/rubocop/cop/cobalt/insecure_hash_algorithm.rb +123 -0
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f2801ac2078b352088c701af34b58f9b88674b73699e40940a89c53c7be4843
|
4
|
+
data.tar.gz: 0e8c1af2bd5fe8d4bee073fb226e10de3b8fdf4a526fdff0133ead3abf543636
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f76c80ad5ff76cc3bc14ef1f40226af2ca7fb3ba4ca26feff3be987cb233535ecc3eb1d77d59a1155b5de971e8bfab9b2d6466e8368d7bbb200897ad413c044
|
7
|
+
data.tar.gz: eeb89417bc4035669050d7007c2eda9b010664e8d8bbb88a07c28ef2fa4181a6e8c24dfe8b5b2b26bb87d6faf4e8a20dc75fc42811aba415a04bb944a135ba6d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# CHANGELOG
|
2
2
|
|
3
|
+
## 0.2.0 (2021-04-14)
|
4
|
+
* Avoid warnings on RSpec `let` with parameter arrays ([#5](https://github.com/cobalthq/cobalt-rubocop/pull/5))
|
5
|
+
* Add new cop `InsecureHashAlgorithm`. ([#3](https://github.com/cobalthq/cobalt-rubocop/pull/3))
|
6
|
+
* Possible need to re-generate `.rubocop_todo.yml` when updating.
|
7
|
+
|
8
|
+
## 0.1.0 (2021-02-10)
|
3
9
|
* Introduce default rules
|
4
10
|
* Introduce rails rules
|
5
11
|
* Introduce rspec rules
|
data/README.md
CHANGED
@@ -1,19 +1,37 @@
|
|
1
1
|
# Cobalt RuboCop
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/cobalt-rubocop.svg)](https://badge.fury.io/rb/cobalt-rubocop)
|
3
|
+
[![GitHub License](https://img.shields.io/github/license/cobalthq/cobalt-rubocop.svg)](https://github.com/cobalthq/cobalt-rubocop/blob/main/LICENSE)
|
4
|
+
![Gem Downloads](https://img.shields.io/gem/dt/cobalt-rubocop)
|
5
|
+
[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](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`
|
29
|
+
- `rubocop-performance`
|
30
|
+
- `rubocop-rails`
|
31
|
+
- `rubocop-rspec`
|
16
32
|
|
33
|
+
### .rubocop.yml
|
34
|
+
Configuration Options:
|
17
35
|
```yaml
|
18
36
|
inherit_gem:
|
19
37
|
cobalt-rubocop:
|
@@ -41,6 +59,32 @@ 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
|
@@ -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.2.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: 2021-
|
11
|
+
date: 2021-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - '='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 2.2.2
|
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.0.9
|
119
136
|
signing_key:
|
120
137
|
specification_version: 4
|
121
138
|
summary: Cobalt RuboCop
|