simplycop 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'bundler/setup'
6
+ require 'simplycop'
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+
11
+ # (If you use this, don't forget to add pry to your Gemfile!)
12
+ # require "pry"
13
+ # Pry.start
14
+
15
+ require 'irb'
16
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplycop/version'
4
+
5
+ module Simplycop
6
+ # NO-OP
7
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CustomCops
4
+ # This cop checks for the presence of dynamically generated constants
5
+ #
6
+ # @example
7
+ # #bad
8
+ # "FOO_BAR".constantize
9
+ #
10
+ # #good
11
+ # FOO_BAR
12
+ #
13
+ class Constantize < RuboCop::Cop::Cop
14
+ MSG = 'Avoid dynamically creating constants.'
15
+
16
+ def_node_matcher :constantizing?, '(send ... :constantize)'
17
+
18
+ def on_send(node)
19
+ return unless constantizing?(node)
20
+
21
+ add_offense(node, location: :selector)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CustomCops
4
+ # This cop checks for dynamically defining methods
5
+ #
6
+ # @example
7
+ # #bad
8
+ # Foo.define_method(:bar) { p 'bar }
9
+ #
10
+ # #good
11
+ # #create the method on the object
12
+ # class Foo
13
+ # def self.bar
14
+ # puts 'bar'
15
+ # end
16
+ # end
17
+ #
18
+ class DefineMethod < RuboCop::Cop::Cop
19
+ MSG = 'Avoid define_method.'
20
+
21
+ def_node_matcher :defining_method?, '(send _ :define_method ...)'
22
+
23
+ def on_send(node)
24
+ return unless defining_method?(node)
25
+
26
+ add_offense(node, location: :selector)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CustomCops
4
+ # This cop checks for usages of `instance_eval`
5
+ #
6
+ # @example
7
+ # #bad
8
+ # class Person
9
+ # end
10
+ #
11
+ # Person.instance_eval do
12
+ # def human?
13
+ # true
14
+ # end
15
+ # end
16
+ #
17
+ # #good
18
+ # class Person
19
+ # def self.human?
20
+ # true
21
+ # end
22
+ # end
23
+ #
24
+ class InstanceEval < RuboCop::Cop::Cop
25
+ MSG = 'Avoid instance_eval.'
26
+
27
+ def_node_matcher :instance_evaling?, '(send _ :instance_eval ...)'
28
+
29
+ def on_send(node)
30
+ return unless instance_evaling?(node)
31
+
32
+ add_offense(node, location: :selector)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CustomCops
4
+ # This cop checks for the presence of `method_missing`
5
+ #
6
+ # @example
7
+ # #bad
8
+ # def method_missing
9
+ # end
10
+ #
11
+ # #good
12
+ #
13
+ # not using method missing
14
+ #
15
+ class MethodMissing < RuboCop::Cop::Cop
16
+ MSG = 'Avoid method missing.'
17
+
18
+ def on_def(node)
19
+ return unless node.method?(:method_missing)
20
+
21
+ add_offense(node)
22
+ end
23
+ alias on_defs on_def
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CustomCops
4
+ class TimecopWithoutBlock < RuboCop::Cop::Cop
5
+ MSG = 'Avoid using `Timecop.%<method>s` without providing a block.'
6
+
7
+ def_node_matcher :timecop_method, '(send (const nil? :Timecop) ${:travel :freeze} ...)'
8
+
9
+ def on_send(node)
10
+ timecop_method(node) do |method_name|
11
+ return if !method_name || first_child_of_block?(node) || last_child_is_a_block(node)
12
+
13
+ add_offense(node, location: :selector, message: format(MSG, method: method_name))
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ # Checks if the given node's parent is a block, and the given node is its first child,
20
+ # which would mean that the block is supplied to the given node (i.e `node { block }`)
21
+ def first_child_of_block?(node)
22
+ return false unless (parent = node.parent)
23
+
24
+ return false unless parent.type == :block
25
+
26
+ parent.children.first == node
27
+ end
28
+
29
+ # Checks whether the last child of the given node is a block.
30
+ # this denotes the following structure:
31
+ # `Timecop.method(arg1, arg2, &block)`, which is also a valid way of passing in a block
32
+ def last_child_is_a_block(node)
33
+ node.children.last&.type == :block_pass
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,34 @@
1
+ module Security
2
+ class CheckForVulnerableCode < RuboCop::Cop::Cop
3
+ RESULT = {}
4
+
5
+ def self.read_file
6
+ gem_path = File.expand_path("#{File.dirname(__FILE__)}../../../../")
7
+
8
+ file = File.open("#{gem_path}/vuln_db.json", "r").read.strip
9
+ json = JSON.parse(file)
10
+ json["vulnerabilities"]["rails"]
11
+ end
12
+
13
+ VULNERABILITY_LIST = read_file
14
+
15
+ VULNERABILITY_LIST.each do |string|
16
+ search = string["search_string"]
17
+ info = string["info"]
18
+
19
+ RESULT[search.to_sym] = info
20
+ def_node_matcher search.to_sym, "(send _ :#{search} _)"
21
+ end
22
+
23
+ def on_send(node)
24
+ _, method = *node
25
+ return unless method
26
+
27
+ if (info = RESULT[method])
28
+ message = "Rails: Possible vulnerability found, CVE Details - #{info} "
29
+
30
+ add_offense(node, location: :selector, message: message)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module Security
2
+ class CSRFTokenValidation < RuboCop::Cop::Cop
3
+ MSG = 'Do not disable authenticity token validation'
4
+ def_node_matcher :skip_before_action, '(send _ :skip_before_action _)'
5
+
6
+ def on_send(node)
7
+ return unless skip_before_action(node)
8
+
9
+ _, _, parts = *node
10
+ method = parts.node_parts
11
+ add_offense(node, location: :selector) if found_match(method[0])
12
+ end
13
+
14
+ def found_match(method)
15
+ [:verify_authenticity_token , 'verify_authenticity_token'].include?(method)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ module Security
2
+ class RejectAllRequestsLocal < RuboCop::Cop::Cop
3
+ RAILS_ENV = ['integration', 'staging', 'production']
4
+
5
+ MSG = "RAILS CONFIG: Restrict usage of option 'consider_all_requests_local' on #{RAILS_ENV.join(', ')} envs"
6
+ def_node_matcher "consider_all_requests_local", '(send (send nil :config) :consider_all_requests_local= (true))'
7
+
8
+ def on_send(node)
9
+ source = node.source
10
+ file_name = node.loc.operator.to_s
11
+
12
+ add_offense(node, location: :selector) if found_match(source) && black_listed?(file_name)
13
+ end
14
+
15
+ def black_listed?(string)
16
+ RAILS_ENV.each_with_object([]) do |env, results|
17
+ results << string.include?(env)
18
+ end.any?(true)
19
+ end
20
+
21
+ def found_match(string)
22
+ string.match(/config.consider_all_requests\S?.*=\s?.*true/) ? true : false
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # === USE Semantic Versioning ===
4
+ # MAJOR version when you make incompatible API changes,
5
+ # MINOR version when you add functionality in a backwards compatible manner
6
+ # PATCH version when you make backwards compatible bug fixes.
7
+ #
8
+
9
+ module Simplycop
10
+ VERSION = '1.0.0.pre'
11
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'simplycop/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'simplycop'
9
+ spec.version = Simplycop::VERSION
10
+ spec.authors = ['Simply Business']
11
+ spec.email = ['tech@simplybusiness.co.uk']
12
+ spec.required_ruby_version = '>= 2.6.0'
13
+ spec.license = 'Copyright SimplyBusiness'
14
+ spec.summary = 'Provides a single point of reference for common rubocop rules.'
15
+ spec.description = 'Require this gem in your application to use Simply Business common rubocop rules.'
16
+ spec.homepage = 'https://github.com/simplybusiness/simplycop'
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'rubocop', '~> 1.3.1'
21
+ spec.add_dependency 'rubocop-rails', '~> 2.8.1'
22
+ spec.add_dependency 'rubocop-rspec', '~> 2.0.0'
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake', '>= 12.3.3'
25
+ spec.add_development_dependency 'rspec', '~> 3.10'
26
+ end
@@ -0,0 +1,8 @@
1
+ {"vulnerabilities":
2
+ {"rails": [
3
+ {
4
+ "search_string": "caches_page",
5
+ "info": "https://nvd.nist.gov/vuln/detail/CVE-2020-8159"
6
+ }
7
+ ]}
8
+ }
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simplycop
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre
5
+ platform: ruby
6
+ authors:
7
+ - Simply Business
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.8.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.8.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop-rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 12.3.3
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 12.3.3
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'
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'
97
+ description: Require this gem in your application to use Simply Business common rubocop
98
+ rules.
99
+ email:
100
+ - tech@simplybusiness.co.uk
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".custom_simplycop.yml"
106
+ - ".github/workflows/ci.yml"
107
+ - ".github/workflows/publish_gem.yml"
108
+ - ".github/workflows/version_forget_me_not.yml"
109
+ - ".gitignore"
110
+ - ".rspec"
111
+ - ".rubocop.yml"
112
+ - ".ruby-version"
113
+ - ".simplycop.yml"
114
+ - ".simplycop_metaprogramming.yml"
115
+ - ".simplycop_rails.yml"
116
+ - ".simplycop_rspec.yml"
117
+ - ".simplycop_security.yml"
118
+ - CODEOWNERS
119
+ - Gemfile
120
+ - README.md
121
+ - Rakefile
122
+ - bin/console
123
+ - bin/setup
124
+ - lib/simplycop.rb
125
+ - lib/simplycop/custom_cops/constantize.rb
126
+ - lib/simplycop/custom_cops/define_method.rb
127
+ - lib/simplycop/custom_cops/instance_eval.rb
128
+ - lib/simplycop/custom_cops/method_missing.rb
129
+ - lib/simplycop/custom_cops/timecop_without_block.rb
130
+ - lib/simplycop/security/check_for_vulnerable_code.rb
131
+ - lib/simplycop/security/csrf_token_validation.rb
132
+ - lib/simplycop/security/reject_all_requests_local.rb
133
+ - lib/simplycop/version.rb
134
+ - simplycop.gemspec
135
+ - vuln_db.json
136
+ homepage: https://github.com/simplybusiness/simplycop
137
+ licenses:
138
+ - Copyright SimplyBusiness
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: 2.6.0
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">"
152
+ - !ruby/object:Gem::Version
153
+ version: 1.3.1
154
+ requirements: []
155
+ rubygems_version: 3.1.4
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: Provides a single point of reference for common rubocop rules.
159
+ test_files: []