spektr 0.5.2 → 0.5.4

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: 07ac33de0dc43a2bd98945e035ceda36db6d48c95fc6cc1ae5625d2599921911
4
- data.tar.gz: 216f3ab944681799b61d8b880710c8d136a934260d504bb167ae2bad41c0e5be
3
+ metadata.gz: 3856f34c87bf7f347c90149e5cc0a824e68d80df6c6a4704a204e4862ea3e54b
4
+ data.tar.gz: f0c98f054f09841c3de0e7f756c80537b5d0a409a2fe0a70d555b63715958691
5
5
  SHA512:
6
- metadata.gz: b68041c229127905c5d426003ed9fcacb51d818b497270600a25d7c1648350e40b9db9fb5f29b7bd1bd089466effd01cc5ecc3b77bf5e49f17956682684f4ea9
7
- data.tar.gz: 1e98efc4bb04e89b886c79decb345f5ab189922d7e0ae9a5d90ff1c4c418a470902cfccdeb3f862e9fe42b0e9c67ddc5f4869902ab6d18cc07ed270b942fe4b8
6
+ metadata.gz: fb99134225086acbaab6417f03594c7cb1b44893bdd413faf5056d3990afdd8e6bea3812c6a5a61344fc518e7d47b78bdbe49dfdb49e75722f6c5303df43101a
7
+ data.tar.gz: 7c20a2d6f2ec1a7c1a5e006b2ce4bb41e527a55fae099fd66d4e120f7fdffd9c6849496269abd998226f303b4602b5ac23b703a8be448abcd851a4f25bdb974a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.5.4
6
+
7
+ * more parser fixes
8
+
9
+
10
+ ## 0.5.3
11
+
12
+ * parser fixes
13
+
5
14
  ## 0.5.2
6
15
 
7
16
  * handle nil nodes
@@ -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
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
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
@@ -67,6 +67,10 @@ module Spektr
67
67
  return true if user_input?(element.key)
68
68
  return true if user_input?(element.value)
69
69
  end
70
+ when :array_node
71
+ node.elements.each do |element|
72
+ return true if user_input?(element)
73
+ end
70
74
  # TODO: make this better. ivars can be overridden in the view as well and
71
75
  # can be set in non controller targets too
72
76
  when :instance_variable_read_node
@@ -84,26 +88,84 @@ module Spektr
84
88
  end
85
89
  end
86
90
  when :local_variable_read_node
87
- return user_input?(@target.lvars.find{|n| n.name == node.name })
91
+ variable = @target.lvars.find do |n|
92
+ n.name == node.name
93
+ end
94
+ return if variable && variable.location.start_line == node.location.start_line
95
+ return user_input?(variable)
96
+ when :instance_variable_or_write_node, :local_variable_or_write_node
97
+ return user_input?(node.value)
88
98
  when :instance_variable_write_node, :local_variable_write_node
89
99
  return user_input? node.value
100
+ when :and_node, :or_node
101
+ return user_input?(node.left)
102
+ return user_input?(node.right)
103
+ when :splat_node
104
+ return user_input? node.expression
90
105
  when :parentheses_node
91
106
  node.body.body.each do |item|
92
107
  return user_input? item
93
108
  end
94
- when :string_node, :symbol_node, :constant_read_node, :integer_node, :true_node, :constant_path_node, :nil_node
109
+ when :string_node, :symbol_node, :constant_read_node, :integer_node, :true_node, :constant_path_node, :nil_node, :true_node, :false_node, :self_node, :global_variable_read_node, :and_node
95
110
  # do nothing
96
111
  else
97
- raise "Unknown argument type #{node.type.inspect} #{node.inspect}"
112
+ Spektr::Logger.debug "Unknown argument type #{node.type.inspect} #{node.inspect}"
98
113
  end
99
114
  false
100
115
  end
101
116
 
102
117
  # TODO: this doesn't work properly
103
118
  def model_attribute?(node)
119
+ return false if node.nil?
104
120
  model_names = @app.models.collect(&:name)
105
121
  case node.type
106
- when :local_variable_read_node, :instance_variable_read_node
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
107
169
  # TODO: handle helpers here too
108
170
  if ["Spektr::Targets::Controller", "Spektr::Targets::View"].include?(@target.class.name)
109
171
  actions = []
@@ -119,27 +181,25 @@ module Spektr
119
181
  end
120
182
  end
121
183
  end
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
184
+ when :instance_variable_or_write, :local_variable_or_write_node
185
+ return model_attribute?(node.value)
186
+ when :instance_variable_write_node, :local_variable_write_node
187
+ return model_attribute? node.value
188
+ when :and_node, :or_node
189
+ return model_attribute?(node.left)
190
+ return model_attribute?(node.right)
191
+ when :splat_node
192
+ return model_attribute? node.expression
129
193
  when :parentheses_node
130
194
  node.body.body.each do |item|
131
195
  return model_attribute? item
132
196
  end
133
197
  when :constant_read_node
134
198
  return true if model_names.include? node.name.to_s
135
- when :interpolated_string_node
136
- node.parts.each do |item|
137
- return model_attribute? item
138
- end
139
- when :string_node, :symbol_node, :integer_node, :constant_path_node, :nil_node
199
+ when :string_node, :symbol_node, :integer_node, :constant_path_node, :nil_node, :true_node, :false_node, :self_node, :global_variable_read_node
140
200
  # do nothing
141
201
  else
142
- raise "Unknown argument type #{node.type}"
202
+ Spektr::Logger.debug "Unknown argument type #{node.type}"
143
203
  end
144
204
  end
145
205
 
@@ -26,7 +26,11 @@ module Spektr
26
26
  next unless call.arguments
27
27
  ::Spektr.logger.debug "#{@target.path} #{call.location.start_line} #{call.arguments.arguments[1].inspect}"
28
28
  next unless call.arguments.arguments[1]
29
- next if call.arguments.arguments[1].name =~ /_url$|_path$/
29
+ require 'byebug'
30
+ if call.arguments.arguments[1] && call.arguments.arguments[1].respond_to?(:name)
31
+ name = call.arguments.arguments[1].name
32
+ end
33
+ next if name && name =~ /_url$|_path$/
30
34
  if user_input? call.arguments.arguments[1]
31
35
  warn! @target, self, call.location, "Cross-Site Scripting: Unsafe user supplied value in link_to"
32
36
  end
@@ -16,7 +16,7 @@ module Spektr
16
16
  calls = []
17
17
  model_names.each do |receiver|
18
18
  [:new, :build, :create].each do |method|
19
- calls.concat @target.find_calls(method, receiver.to_sym)
19
+ calls.concat @target.find_calls(method, receiver&.to_sym)
20
20
  end
21
21
  end
22
22
  calls.each do |call|
@@ -25,9 +25,9 @@ module Spektr
25
25
  ::Spektr.logger.debug "Mass assignment check at #{call.location.start_line}"
26
26
  if user_input?(argument)
27
27
  # we check for permit! separately
28
- next if argument.name == :permit!
28
+ next if argument.respond_to?(:name) && argument.name == :permit!
29
29
  # check for permit with arguments
30
- next if argument.name == :permit && argument.arguments
30
+ next if argument.respond_to?(:name) && argument.name == :permit && argument.arguments
31
31
  warn! @target, self, call.location, "Mass assignment"
32
32
  end
33
33
  end
@@ -43,7 +43,12 @@ module Spektr
43
43
  warn! @target, self, call.location, "Cross-Site Scripting: Unescaped user input"
44
44
  end
45
45
  if model_attribute?(call.receiver)
46
- warn! @target, self, call.location, "Cross-Site Scripting: Unescaped model attribute #{call.receiver.name}"
46
+ name = if call.receiver.respond_to?(:name)
47
+ call.receiver.name
48
+ else
49
+ ""
50
+ end
51
+ warn! @target, self, call.location, "Cross-Site Scripting: Unescaped model attribute #{name}"
47
52
  end
48
53
  end
49
54
  end
@@ -1,3 +1,3 @@
1
1
  module Spektr
2
- VERSION = '0.5.2'
2
+ VERSION = '0.5.4'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spektr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Molnar