spektr 0.5.3 → 0.5.5
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/spektr/checks/base.rb +61 -42
- data/lib/spektr/checks/mass_assignment.rb +13 -6
- data/lib/spektr/checks/sqli.rb +3 -1
- data/lib/spektr/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b3f2e35ede68f8a611ce58a5ad3a4fc251e3d18191b9f1bc7fb314666d789063
|
|
4
|
+
data.tar.gz: 908740bb4515316fa1c5a69a0b583ea282251a3483fc33a704f83e63521fe249
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f92ec1f4949da94bad355d9062b825fbb96480bdf6fe9fb424a421afbaa132cae4b9d0313d0f7af902e25b6ac6141ddc871ecd01cc8f4e4118bd0e7082f362d3
|
|
7
|
+
data.tar.gz: b6e240e0449e4fb858ae591aaeec936a18502741e105b56b30f00c05c6286a7ce690cfb3ae7d66ce07c5f53c64eb8f6bff55420b0f016d2764d30cba5bb090eb
|
data/CHANGELOG.md
CHANGED
data/lib/spektr/checks/base.rb
CHANGED
|
@@ -54,11 +54,11 @@ module Spektr
|
|
|
54
54
|
return true if user_input?(argument)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
when :embedded_statements_node, :if_node, :else_node
|
|
57
|
+
when :embedded_statements_node, :if_node, :else_node, :case_node, :embedded_variable_node
|
|
58
58
|
node.statements.body.each do |item|
|
|
59
59
|
return true if user_input? item
|
|
60
60
|
end
|
|
61
|
-
when :interpolated_string_node, :interpolated_x_string_node, :interpolated_symbol_node
|
|
61
|
+
when :interpolated_string_node, :interpolated_x_string_node, :interpolated_symbol_node, :interpolated_regular_expression_node
|
|
62
62
|
node.parts.each do |part|
|
|
63
63
|
return true if user_input?(part)
|
|
64
64
|
end
|
|
@@ -93,32 +93,79 @@ module Spektr
|
|
|
93
93
|
end
|
|
94
94
|
return if variable && variable.location.start_line == node.location.start_line
|
|
95
95
|
return user_input?(variable)
|
|
96
|
-
when :local_variable_or_write_node
|
|
96
|
+
when :instance_variable_or_write_node, :local_variable_or_write_node
|
|
97
97
|
return user_input?(node.value)
|
|
98
|
+
when :instance_variable_write_node, :local_variable_write_node
|
|
99
|
+
return user_input? node.value
|
|
98
100
|
when :and_node, :or_node
|
|
99
101
|
return user_input?(node.left)
|
|
100
102
|
return user_input?(node.right)
|
|
101
|
-
when :instance_variable_write_node, :local_variable_write_node
|
|
102
|
-
return user_input? node.value
|
|
103
103
|
when :splat_node
|
|
104
104
|
return user_input? node.expression
|
|
105
105
|
when :parentheses_node
|
|
106
106
|
node.body.body.each do |item|
|
|
107
107
|
return user_input? item
|
|
108
108
|
end
|
|
109
|
-
when :string_node, :symbol_node, :constant_read_node, :integer_node, :
|
|
109
|
+
when :string_node, :symbol_node, :constant_read_node, :integer_node, :constant_path_node, :nil_node, :true_node, :false_node, :self_node, :global_variable_read_node
|
|
110
110
|
# do nothing
|
|
111
111
|
else
|
|
112
|
-
|
|
112
|
+
::Spektr.logger.debug "Unknown argument type #{node.type.inspect} #{node.inspect}"
|
|
113
113
|
end
|
|
114
114
|
false
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
# TODO: this doesn't work properly
|
|
118
118
|
def model_attribute?(node)
|
|
119
|
+
return false if node.nil?
|
|
119
120
|
model_names = @app.models.collect(&:name)
|
|
120
121
|
case node.type
|
|
121
|
-
when :
|
|
122
|
+
when :call_node
|
|
123
|
+
return model_attribute?(node.receiver) if node.receiver
|
|
124
|
+
if node.arguments
|
|
125
|
+
node.arguments.arguments.each do |argument|
|
|
126
|
+
return true if model_attribute?(argument)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
when :embedded_statements_node, :if_node, :else_node, :case_node, :embedded_variable_node
|
|
130
|
+
node.statements.body.each do |item|
|
|
131
|
+
return true if model_attribute? item
|
|
132
|
+
end
|
|
133
|
+
when :interpolated_string_node, :interpolated_x_string_node, :interpolated_symbol_node, :interpolated_regular_expression_node
|
|
134
|
+
node.parts.each do |part|
|
|
135
|
+
return true if model_attribute?(part)
|
|
136
|
+
end
|
|
137
|
+
when :keyword_hash_node, :hash_node
|
|
138
|
+
node.elements.each do |element|
|
|
139
|
+
return true if model_attribute?(element.key)
|
|
140
|
+
return true if model_attribute?(element.value)
|
|
141
|
+
end
|
|
142
|
+
when :array_node
|
|
143
|
+
node.elements.each do |element|
|
|
144
|
+
return true if model_attribute?(element)
|
|
145
|
+
end
|
|
146
|
+
# TODO: make this better. ivars can be overridden in the view as well and
|
|
147
|
+
# can be set in non controller targets too
|
|
148
|
+
when :_instance_variable_read_node
|
|
149
|
+
return false unless @target.respond_to?(:view_path)
|
|
150
|
+
actions = []
|
|
151
|
+
@app.controllers.each do |controller|
|
|
152
|
+
actions = actions.concat controller.actions.select { |action|
|
|
153
|
+
action.template == @target.view_path
|
|
154
|
+
}
|
|
155
|
+
end
|
|
156
|
+
actions.each do |action|
|
|
157
|
+
next unless action.body
|
|
158
|
+
action.body.each do |exp|
|
|
159
|
+
return true if exp.name == node.name && model_attribute?(exp)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
when :local_variable_read_node
|
|
163
|
+
variable = @target.lvars.find do |n|
|
|
164
|
+
n.name == node.name
|
|
165
|
+
end
|
|
166
|
+
return if variable && variable.location.start_line == node.location.start_line
|
|
167
|
+
return model_attribute?(variable)
|
|
168
|
+
when :instance_variable_read_node
|
|
122
169
|
# TODO: handle helpers here too
|
|
123
170
|
if ["Spektr::Targets::Controller", "Spektr::Targets::View"].include?(@target.class.name)
|
|
124
171
|
actions = []
|
|
@@ -134,53 +181,25 @@ module Spektr
|
|
|
134
181
|
end
|
|
135
182
|
end
|
|
136
183
|
end
|
|
137
|
-
when :local_variable_or_write_node
|
|
184
|
+
when :instance_variable_or_write, :local_variable_or_write_node
|
|
138
185
|
return model_attribute?(node.value)
|
|
186
|
+
when :instance_variable_write_node, :local_variable_write_node
|
|
187
|
+
return model_attribute? node.value
|
|
139
188
|
when :and_node, :or_node
|
|
140
189
|
return model_attribute?(node.left)
|
|
141
190
|
return model_attribute?(node.right)
|
|
142
|
-
when :
|
|
143
|
-
return model_attribute?
|
|
144
|
-
if node.arguments
|
|
145
|
-
node.arguments.arguments.each do |argument|
|
|
146
|
-
return true if model_attribute?(argument)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
when :keyword_hash_node, :hash_node
|
|
150
|
-
node.elements.each do |element|
|
|
151
|
-
return true if model_attribute?(element.key)
|
|
152
|
-
return true if model_attribute?(element.value)
|
|
153
|
-
end
|
|
154
|
-
when :array_node
|
|
155
|
-
node.elements.each do |element|
|
|
156
|
-
return true if model_attribute?(element)
|
|
157
|
-
end
|
|
191
|
+
when :splat_node
|
|
192
|
+
return model_attribute? node.expression
|
|
158
193
|
when :parentheses_node
|
|
159
194
|
node.body.body.each do |item|
|
|
160
195
|
return model_attribute? item
|
|
161
196
|
end
|
|
162
|
-
when :interpolated_string_node, :interpolated_x_string_node, :interpolated_symbol_node
|
|
163
|
-
node.parts.each do |part|
|
|
164
|
-
return true if model_attribute?(part)
|
|
165
|
-
end
|
|
166
|
-
when :embedded_statements_node, :if_node, :else_node
|
|
167
|
-
node.statements.body.each do |item|
|
|
168
|
-
return true if model_attribute? item
|
|
169
|
-
end
|
|
170
|
-
when :instance_variable_write_node, :local_variable_write_node
|
|
171
|
-
return model_attribute? node.value
|
|
172
197
|
when :constant_read_node
|
|
173
198
|
return true if model_names.include? node.name.to_s
|
|
174
|
-
when :interpolated_string_node
|
|
175
|
-
node.parts.each do |item|
|
|
176
|
-
return model_attribute? item
|
|
177
|
-
end
|
|
178
|
-
when :splat_node
|
|
179
|
-
return model_attribute? node.expression
|
|
180
199
|
when :string_node, :symbol_node, :integer_node, :constant_path_node, :nil_node, :true_node, :false_node, :self_node, :global_variable_read_node
|
|
181
200
|
# do nothing
|
|
182
201
|
else
|
|
183
|
-
|
|
202
|
+
Spektr.logger.debug "Unknown argument type #{node.type}"
|
|
184
203
|
end
|
|
185
204
|
end
|
|
186
205
|
|
|
@@ -23,13 +23,20 @@ module Spektr
|
|
|
23
23
|
argument = call.arguments&.arguments&.first
|
|
24
24
|
next if argument.nil?
|
|
25
25
|
::Spektr.logger.debug "Mass assignment check at #{call.location.start_line}"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
next unless user_input?(argument)
|
|
27
|
+
if argument.type == :local_variable_read_node
|
|
28
|
+
variable = @target.lvars.find do |n|
|
|
29
|
+
n.name == argument.name
|
|
30
|
+
end
|
|
31
|
+
param = variable.value
|
|
32
|
+
else
|
|
33
|
+
param = argument
|
|
32
34
|
end
|
|
35
|
+
# we check for permit! separately
|
|
36
|
+
next if param.respond_to?(:name) && param.name == :permit!
|
|
37
|
+
# check for permit with arguments
|
|
38
|
+
next if param.respond_to?(:name) && param.name == :permit && param.arguments
|
|
39
|
+
warn! @target, self, call.location, "Mass assignment"
|
|
33
40
|
end
|
|
34
41
|
@target.find_calls(:permit!).each do |call|
|
|
35
42
|
unless call.arguments
|
data/lib/spektr/checks/sqli.rb
CHANGED
|
@@ -19,7 +19,9 @@ module Spektr
|
|
|
19
19
|
|
|
20
20
|
].each do |m|
|
|
21
21
|
@target.find_calls(m).each do |call|
|
|
22
|
-
|
|
22
|
+
arguments = call.arguments&.arguments&.first
|
|
23
|
+
next if arguments && arguments.type == :keyword_hash_node
|
|
24
|
+
check_argument(arguments, m, call)
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
[:calculate].each do |m|
|
data/lib/spektr/version.rb
CHANGED