platformos-check 0.4.5 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -1
- data/config/default.yml +8 -0
- data/docs/checks/form_action.md +1 -1
- data/docs/checks/form_authenticity_token.md +55 -0
- data/docs/checks/unreachable_code.md +66 -0
- data/lib/platformos_check/checks/form_authenticity_token.rb +21 -0
- data/lib/platformos_check/checks/unreachable_code.rb +114 -0
- data/lib/platformos_check/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aebbd738b1045c874460b7f1de2cf2774297f36136fce816521dda29ce371652
|
4
|
+
data.tar.gz: c348e3afc68f2a664fe1ad313d41497ad7c977f8de72f3b82df9dda297926c38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 368d39315a05ab34eff3797012af56775ca9a5ff4d8209ed0c44aa2916f97fe5740afa859bbfbbdf34409aa40967efe4236b2394eafcdecfc313c97f62a4dba7
|
7
|
+
data.tar.gz: f912bda1de7e0be84e887ab2f19cde9072e03468ea52265f910e20ff5a7317b7f7f4e6fe83aef690350f21543ffbd495e01c72eddca5c393acfc5500055d6939
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
v0.4.
|
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: []
|
data/docs/checks/form_action.md
CHANGED
@@ -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
|
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.
|
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-
|
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
|