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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c08db73a41f4beaee02f72349ba019f38884ed65030ca622cffb6e2bb76d0dfe
4
- data.tar.gz: '06588084616ac4a8e65741a3c251de8988faf4e2157bef50a8f290f64c7a5dd4'
3
+ metadata.gz: 6f2801ac2078b352088c701af34b58f9b88674b73699e40940a89c53c7be4843
4
+ data.tar.gz: 0e8c1af2bd5fe8d4bee073fb226e10de3b8fdf4a526fdff0133ead3abf543636
5
5
  SHA512:
6
- metadata.gz: ccf9019e8758ea7b9c170c89a6f4cda9417251a114776b0682e9dd08da99df921641efd67d1bb4e64746af9d895576ddebe3cd6d56430ddc3011ed9c92958335
7
- data.tar.gz: 35fdb07709b25dbb699f730a8aa3c13d30a244aad2d7745f1db4542d03e063dd8cc5dc7922fed21311faf941ab9e8982e479110af7b97fe1e57d8a22d92e862d
6
+ metadata.gz: 8f76c80ad5ff76cc3bc14ef1f40226af2ca7fb3ba4ca26feff3be987cb233535ecc3eb1d77d59a1155b5de971e8bfab9b2d6466e8368d7bbb200897ad413c044
7
+ data.tar.gz: eeb89417bc4035669050d7007c2eda9b010664e8d8bbb88a07c28ef2fa4181a6e8c24dfe8b5b2b26bb87d6faf4e8a20dc75fc42811aba415a04bb944a135ba6d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
- # 0.1.0
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
- ```ruby
10
- group :development do
11
- gem 'cobalt-rubocop', require: false, git: 'https://github.com/cobalthq/cobalt-rubocop', branch: :main
12
- end
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
- ### .rubocop.yml
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
- ### Publishing the gem
59
- If you have access to publish the gem on rubygems:
60
- ```shell
61
- rake build
62
- cd pkg
63
- gem push cobalt-rubocop-<version_number>.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
@@ -1,5 +1,6 @@
1
1
  require:
2
2
  - rubocop-performance
3
+ - rubocop/cop/cobalt
3
4
 
4
5
  AllCops:
5
6
  NewCops: enable
@@ -57,3 +58,6 @@ Style/IfUnlessModifier:
57
58
 
58
59
  Style/ClassAndModuleChildren:
59
60
  EnforcedStyle: nested
61
+
62
+ Cobalt/InsecureHashAlgorithm:
63
+ Enabled: true
data/config/rspec.yml CHANGED
@@ -14,6 +14,7 @@ RSpec/MessageSpies:
14
14
  RSpec/VariableName:
15
15
  IgnoredPatterns:
16
16
  - ^Authorization
17
+ - '\[\]$' # For array parameters in rswag like `let(:'<parameter_name>[]')`
17
18
 
18
19
  RSpec/MultipleMemoizedHelpers:
19
20
  Max: 17
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cobalt
5
+ VERSION = '0.2.0'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop/cop/cobalt/insecure_hash_algorithm'
@@ -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.1.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-02-10 00:00:00.000000000 Z
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.1.2
135
+ rubygems_version: 3.0.9
119
136
  signing_key:
120
137
  specification_version: 4
121
138
  summary: Cobalt RuboCop