platformos-check 0.4.5 → 0.4.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e25de2efbace27cbcb87f0166520a416c0a275dccd641524a3f3ea1b95190779
4
- data.tar.gz: d4bc78729da09cb589caa3472e01c4735161d454b697560a894877073d21398e
3
+ metadata.gz: aebbd738b1045c874460b7f1de2cf2774297f36136fce816521dda29ce371652
4
+ data.tar.gz: c348e3afc68f2a664fe1ad313d41497ad7c977f8de72f3b82df9dda297926c38
5
5
  SHA512:
6
- metadata.gz: 5dd2688e9b917dc3af698bcbf135bafc016bbfba8d24c46bd62528315d594322cf186913cbd6319a8d9275f8357a5d2d8067b542bd5fb90828532556464e4237
7
- data.tar.gz: b1308c97e7721df699c423e9c1e111fee82e0bd31e79c8b55a1300baf5547fe115c35a9435ed16e5e2c68c825b230a6b710aba225d32f62a1ea3bee47a2204bd
6
+ metadata.gz: 368d39315a05ab34eff3797012af56775ca9a5ff4d8209ed0c44aa2916f97fe5740afa859bbfbbdf34409aa40967efe4236b2394eafcdecfc313c97f62a4dba7
7
+ data.tar.gz: f912bda1de7e0be84e887ab2f19cde9072e03468ea52265f910e20ff5a7317b7f7f4e6fe83aef690350f21543ffbd495e01c72eddca5c393acfc5500055d6939
data/CHANGELOG.md CHANGED
@@ -1,4 +1,14 @@
1
- v0.4.5 / 2023-12-04
1
+ v0.4.7 / 2023-12-22
2
+ ==================
3
+
4
+ * Add UnreachableCode check
5
+
6
+ v0.4.6 / 2023-12-19
7
+ ==================
8
+
9
+ * Add FormAuthenticityToken check
10
+
11
+ v0.4.5 / 2023-12-19
2
12
  ==================
3
13
 
4
14
  * Add FormAction check
data/config/default.yml CHANGED
@@ -50,6 +50,10 @@ UnknownFilter:
50
50
  enabled: true
51
51
  ignore: []
52
52
 
53
+ UnreachableCode:
54
+ enabled: true
55
+ ignore: []
56
+
53
57
  UnusedAssign:
54
58
  enabled: true
55
59
  ignore: []
@@ -91,6 +95,10 @@ FormAction:
91
95
  enabled: true
92
96
  ignore: []
93
97
 
98
+ FormAuthenticityToken:
99
+ enabled: true
100
+ ignore: []
101
+
94
102
  HtmlParsingError:
95
103
  enabled: true
96
104
  ignore: []
@@ -45,7 +45,7 @@ There should be no cases where disabling this rule is needed.
45
45
 
46
46
  ## Version
47
47
 
48
- This check has been introduced in PlatformOS Check 0.45.0.
48
+ This check has been introduced in PlatformOS Check 0.4.5.
49
49
 
50
50
  ## Resources
51
51
 
@@ -0,0 +1,55 @@
1
+ # Form authenticity token (`FormAuthenticityToken`)
2
+
3
+ In platformOS all POST/PATCH/PUT/DELETE requests are protected from [CSRF Attacks][csrf-attack] through [authenticity_token][page-csrf]
4
+ Form action defines the endpoint to which browser will make a request after submitting it.
5
+
6
+ As a general rule you should include hidden input `<input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">` in every form. Missing it will result in session invalidation and any logged in user will be automatically logged out.
7
+
8
+ ## Check Details
9
+
10
+ This check is aimed at ensuring you have not forgotten to include authenticity_token in a form.
11
+
12
+ :-1: Examples of **incorrect** code for this check:
13
+
14
+ ```liquid
15
+ <form action="dummy/create">
16
+ </form>
17
+ ```
18
+
19
+ :+1: Examples of **correct** code for this check:
20
+
21
+ ```liquid
22
+ <form action="/dummy/create">
23
+ <input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">
24
+ </form>
25
+ ```
26
+
27
+ ## Check Options
28
+
29
+ The default configuration for this check is the following:
30
+
31
+ ```yaml
32
+ FormAuthenticityToken:
33
+ enabled: true
34
+ ```
35
+
36
+ ## When Not To Use It
37
+
38
+ There should be no cases where disabling this rule is needed.
39
+
40
+ ## Version
41
+
42
+ This check has been introduced in PlatformOS Check 0.4.6.
43
+
44
+ ## Resources
45
+
46
+ - [Rule Source][codesource]
47
+ - [Documentation Source][docsource]
48
+ - [platformOS Page documentation][page-csrf]
49
+ - [OWASP Cross Site Request Forgery][csrf-attack]
50
+
51
+ [codesource]: /lib/platformos_check/checks/form_authenticity_token.rb
52
+ [docsource]: /docs/checks/form_authenticity_token.md
53
+ [page-csrf]: https://documentation.platformos.com/developer-guide/pages/pages#post-put-patch-delete-methods-and-cross-site-request-forgery-attacks
54
+ [csrf-attack]: https://owasp.org/www-community/attacks/csrf
55
+
@@ -0,0 +1,66 @@
1
+ # Unreachable code (`UnreachableCode`)
2
+
3
+ Unreachable code reports code that will never be reached, no matter what.
4
+
5
+ ## Check Details
6
+
7
+ This check is aimed at ensuring you will not accidentally write code that will never be reached.
8
+
9
+ :-1: Examples of **incorrect** code for this check:
10
+
11
+ ```liquid
12
+ assign x = "hello"
13
+ break
14
+ log x
15
+ ```
16
+
17
+ ```liquid
18
+ if x
19
+ log x
20
+ else
21
+ break
22
+ log "Stop"
23
+ endif
24
+ ```
25
+
26
+ :+1: Examples of **correct** code for this check:
27
+
28
+ ```liquid
29
+ assign x = "hello"
30
+ log x
31
+ break
32
+ ```
33
+
34
+ ```liquid
35
+ if x
36
+ log x
37
+ else
38
+ log "Stop"
39
+ break
40
+ endif
41
+ ```
42
+
43
+ ## Check Options
44
+
45
+ The default configuration for this check is the following:
46
+
47
+ ```yaml
48
+ UnreachableCode:
49
+ enabled: true
50
+ ```
51
+
52
+ ## When Not To Use It
53
+
54
+ There should be no cases where disabling this rule is needed.
55
+
56
+ ## Version
57
+
58
+ This check has been introduced in PlatformOS Check 0.4.7.
59
+
60
+ ## Resources
61
+
62
+ - [Rule Source][codesource]
63
+ - [Documentation Source][docsource]
64
+
65
+ [codesource]: /lib/platformos_check/checks/unreachable_code.rb
66
+ [docsource]: /docs/checks/unreachable_code.md
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformosCheck
4
+ class FormAuthenticityToken < HtmlCheck
5
+ severity :error
6
+ categories :html
7
+ doc docs_url(__FILE__)
8
+
9
+ AUTHENTICITY_TOKEN_VALUE = /\A\s*{{\s*context\.authenticity_token\s*}}\s*\z/
10
+
11
+ def on_form(node)
12
+ authenticity_toke_inputs = node.children.select { |c| c.name == 'input' && c.attributes['name'] == 'authenticity_token' && c.attributes['value']&.match?(AUTHENTICITY_TOKEN_VALUE) }
13
+ return if authenticity_toke_inputs.size == 1
14
+ return add_offense('Duplicated authenticity_token inputs', node:) if authenticity_toke_inputs.size > 1
15
+
16
+ add_offense('Missing authenticity_token input <input type="hidden" name="authenticity_token" value="{{ context.authenticity_token }}">', node:) do |corrector|
17
+ corrector.insert_after(node, "\n<input type=\"hidden\" name=\"authenticity_token\" value=\"{{ context.authenticity_token }}\">")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlatformosCheck
4
+ # Recommends using {% liquid ... %} if 5 or more consecutive {% ... %} are found.
5
+ class UnreachableCode < LiquidCheck
6
+ severity :error
7
+ category :liquid
8
+ doc docs_url(__FILE__)
9
+
10
+ FLOW_COMMAND = %i[break continue return]
11
+ CONDITION_TYPES = Set.new(%i[condition else_condition])
12
+ INCLUDE_FLOW_COMMAND = %w[break]
13
+
14
+ def on_document(node)
15
+ @processed_files = {}
16
+ check_unreachable_code(node.children)
17
+ end
18
+
19
+ protected
20
+
21
+ def check_unreachable_code(nodes)
22
+ nodes = sanitize_children(nodes)
23
+ nodes.each_cons(2) do |node1, _node2|
24
+ next unless flow_expression?(node1)
25
+
26
+ add_offense("Unreachable code after `#{node1.type_name}`", node: node1)
27
+ end
28
+ flow_expression?(nodes.last)
29
+ end
30
+
31
+ def sanitize_children(children)
32
+ children.reject { |c| c.value.is_a?(String) && c.value.strip == '' }
33
+ end
34
+
35
+ def flow_expression?(node)
36
+ return false if node.nil?
37
+ return true if flow_command?(node)
38
+
39
+ case node.type_name
40
+ when :if, :unless
41
+ check_if(node)
42
+ false
43
+ when :for
44
+ check_for(node)
45
+ false
46
+ when :case
47
+ check_case(node)
48
+ false
49
+ when :try_rc, :try
50
+ check_try(node)
51
+ false
52
+ when :block_body
53
+ node.children.any? { |c| flow_expression?(c) }
54
+ else
55
+ false
56
+ end
57
+ end
58
+
59
+ def check_if(node)
60
+ node.children.each do |condition|
61
+ check_unreachable_code(condition.children.detect(&:block_body?).children)
62
+ end
63
+ end
64
+
65
+ def check_for(node)
66
+ check_unreachable_code(node.children.detect(&:block_body?).children)
67
+ end
68
+
69
+ def check_case(node)
70
+ node.children.each do |condition|
71
+ next unless CONDITION_TYPES.include?(condition.type_name)
72
+
73
+ check_unreachable_code(condition.children.detect(&:block_body?).children)
74
+ end
75
+ end
76
+
77
+ def check_try(node)
78
+ node.children.each do |block_body|
79
+ check_unreachable_code(block_body.children)
80
+ end
81
+ end
82
+
83
+ def flow_command?(node)
84
+ return true if FLOW_COMMAND.include?(node.type_name)
85
+
86
+ return evaluate_include(node.value.template_name_expr) if node.type_name == :include && node.value.template_name_expr.is_a?(String)
87
+
88
+ false
89
+ end
90
+
91
+ def evaluate_include(path)
92
+ return false unless path.is_a?(String)
93
+
94
+ @processed_files[path] ||= include_node_contains_flow_command?(@platformos_app.grouped_files[PlatformosCheck::PartialFile][path]&.parse&.root)
95
+ @processed_files[path]
96
+ end
97
+
98
+ def include_node_contains_flow_command?(root)
99
+ return false if root.nil?
100
+
101
+ root.nodelist.any? do |node|
102
+ if INCLUDE_FLOW_COMMAND.include?(node.respond_to?(:tag_name) && node.tag_name)
103
+ true
104
+ elsif node.respond_to?(:nodelist) && node.nodelist
105
+ include_node_contains_flow_command?(node)
106
+ elsif node.respond_to?(:tag_name) && node.tag_name == 'include' && node.template_name_expr.is_a?(String)
107
+ evaluate_include(node.template_name_expr)
108
+ else
109
+ false
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PlatformosCheck
4
- VERSION = "0.4.5"
4
+ VERSION = "0.4.7"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: platformos-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Bliszczyk
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2023-12-19 00:00:00.000000000 Z
13
+ date: 2023-12-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: graphql
@@ -118,6 +118,7 @@ files:
118
118
  - docs/checks/convert_include_to_render.md
119
119
  - docs/checks/deprecated_filter.md
120
120
  - docs/checks/form_action.md
121
+ - docs/checks/form_authenticity_token.md
121
122
  - docs/checks/html_parsing_error.md
122
123
  - docs/checks/img_lazy_loading.md
123
124
  - docs/checks/img_width_and_height.md
@@ -133,6 +134,7 @@ files:
133
134
  - docs/checks/template_length.md
134
135
  - docs/checks/undefined_object.md
135
136
  - docs/checks/unknown_filter.md
137
+ - docs/checks/unreachable_code.md
136
138
  - docs/checks/unused_assign.md
137
139
  - docs/checks/unused_partial.md
138
140
  - docs/checks/valid_yaml.md
@@ -161,6 +163,7 @@ files:
161
163
  - lib/platformos_check/checks/convert_include_to_render.rb
162
164
  - lib/platformos_check/checks/deprecated_filter.rb
163
165
  - lib/platformos_check/checks/form_action.rb
166
+ - lib/platformos_check/checks/form_authenticity_token.rb
164
167
  - lib/platformos_check/checks/html_parsing_error.rb
165
168
  - lib/platformos_check/checks/img_lazy_loading.rb
166
169
  - lib/platformos_check/checks/img_width_and_height.rb
@@ -176,6 +179,7 @@ files:
176
179
  - lib/platformos_check/checks/template_length.rb
177
180
  - lib/platformos_check/checks/undefined_object.rb
178
181
  - lib/platformos_check/checks/unknown_filter.rb
182
+ - lib/platformos_check/checks/unreachable_code.rb
179
183
  - lib/platformos_check/checks/unused_assign.rb
180
184
  - lib/platformos_check/checks/unused_partial.rb
181
185
  - lib/platformos_check/checks/valid_yaml.rb