brakeman-lib 8.0.4 → 8.0.6

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: d07db98e56b03b45fd3347a5982628ab3421d8bba0c1a1d55a3b685432ef8375
4
- data.tar.gz: 1245d911d4356d014e616bb387810c3879e8a68919fd1f1f173a4a21cf6c8fe9
3
+ metadata.gz: 93cfb6ec4cc35376d35e8fe361e6b893bfe39858136d53a29196dd5c5869658d
4
+ data.tar.gz: eb788145060b1e41cf0f18d56395b13681ba0daf72f1948dc8ab0f73e3449b50
5
5
  SHA512:
6
- metadata.gz: 48540c3c00cf275afe01c3194302d48bd0e8e12602f1abd5a81bc99c1cc13ca5fb48fcf630879dc6a851e88559404d210fb6e0d6324a7203a3ad274b18116504
7
- data.tar.gz: 056150df12092b1d16a1b56214d7a268627fe58d7249071c0ef4871aa0c289c184753f2c8468374dd1046beb77515d306c9416033901f0424452ca920ac71993
6
+ metadata.gz: 9698bfe45b5988178cbe7e134dd0134c00618ec786c0cfcea2a01cce139f1a0e8317dd2b7d1e54ae24b8fe0b4c23687fa02742333ff4c2226cf382a2806597ab
7
+ data.tar.gz: 9e1ad4ea0ee656909be88cdcb167f0e9eda87c4af2b8a43c58f27e4d8c9c4c1922885958a90a8cb1a71c0049dbfeb2369e3f0751c68bc259d5b78578bdf6725d
data/CHANGES.md CHANGED
@@ -1,3 +1,20 @@
1
+ # 8.0.6 - 2026-08-13
2
+
3
+ * Fix EOL date for Rails 8.0 (yeaseul-kim)
4
+ * Add EOL dates for Rails 8.1 and Ruby 4.0
5
+ * Fix command injection false positives (Jacob Evelyn)
6
+ * Fix unused variable warning (viralpraxis)
7
+
8
+ # 8.0.5 - 2026-06-12
9
+
10
+ * Add `quote_schema_name` to safe quote method list (Zsolt Kozaroczy)
11
+ * Fix SQL injection false positive for `compact_blank`/`compact` on permitted params (Arpit Jain)
12
+ * Fix inline render false positive for local named `text` (Arpit Jain)
13
+ * Fix HAML crash on `.raw` calls (Federico Franco)
14
+ * Fix Ruby version parsing - especially for non-CRuby versions (Chris Southerland Jr)
15
+ * Fix `TemplateAliasProcessor#template_name` arity (viralpraxis)
16
+ * Reduce false positives when using shell escaping
17
+
1
18
  # 8.0.4 - 2026-02-26
2
19
 
3
20
  * Load 'date' library for `--ensure-latest`
@@ -25,6 +25,7 @@ class Brakeman::CheckEOLRails < Brakeman::EOLCheck
25
25
  ['7.0.0', '7.0.99'] => Date.new(2025, 4, 1),
26
26
  ['7.1.0', '7.1.99'] => Date.new(2025, 10, 1),
27
27
  ['7.2.0', '7.2.99'] => Date.new(2026, 8, 9),
28
- ['8.0.0', '8.0.99'] => Date.new(2026, 10, 7),
28
+ ['8.0.0', '8.0.99'] => Date.new(2026, 11, 7),
29
+ ['8.1.0', '8.1.99'] => Date.new(2027, 10, 10),
29
30
  }
30
31
  end
@@ -26,5 +26,6 @@ class Brakeman::CheckEOLRuby < Brakeman::EOLCheck
26
26
  ['3.2.0', '3.2.99'] => Date.new(2026, 3, 31),
27
27
  ['3.3.0', '3.3.99'] => Date.new(2027, 3, 31),
28
28
  ['3.4.0', '3.4.99'] => Date.new(2028, 3, 31),
29
+ ['4.0.0', '4.0.99'] => Date.new(2029, 3, 31),
29
30
  }
30
31
  end
@@ -55,6 +55,13 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
55
55
  first_arg = call.first_arg
56
56
  failure = nil
57
57
 
58
+ # All spawn-family methods optionally accept an env hash as the first
59
+ # argument. Strip it so first_arg always points to the command name.
60
+ if hash?(first_arg)
61
+ args.delete_at(1)
62
+ first_arg = args[1]
63
+ end
64
+
58
65
  case call.method
59
66
  when :popen
60
67
  # Normally, if we're in a `popen` call, we only are worried about shell
@@ -99,14 +106,17 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
99
106
 
100
107
  break if failure
101
108
  end
102
- when :system, :exec
103
- # Normally, if we're in a `system` or `exec` call, we only are worried
104
- # about shell injection when there's a single argument, because comma-
105
- # separated arguments are always escaped by Ruby. However, an exception is
106
- # when the first two arguments are something like "bash -c" because then
107
- # the third argument is effectively the command being run and might be
108
- # a malicious executable if it comes (partially or fully) from user input.
109
- if dash_c_shell_command?(first_arg, call.second_arg)
109
+ when :system, :exec, :spawn, :capture2, :capture2e, :capture3,
110
+ :popen2, :popen2e, :popen3
111
+ # Comma-separated arguments are passed directly to execve without a
112
+ # shell, so only the first argument (the command name) needs checking.
113
+ # Exception: `bash -c <script>` the script is the injection vector.
114
+ #
115
+ # All of these methods accept an optional trailing options hash
116
+ # (e.g. stdin_data:, chdir:); strip it before checking.
117
+ args.pop if hash?(args.last) && args.length > 2
118
+
119
+ if dash_c_shell_command?(first_arg, args[2])
110
120
  failure = include_user_input?(args[3]) ||
111
121
  dangerous_interp?(args[3]) ||
112
122
  dangerous_string_building?(args[3])
@@ -115,16 +125,6 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
115
125
  dangerous_interp?(first_arg) ||
116
126
  dangerous_string_building?(first_arg)
117
127
  end
118
- when :capture2, :capture2e, :capture3
119
- # Open3 capture methods can take a :stdin_data argument which is used as the
120
- # the input to the called command so it is not succeptable to command injection.
121
- # As such if the last argument is a hash (and therefore execution options) it
122
- # should be ignored
123
-
124
- args.pop if hash?(args.last) && args.length > 2
125
- failure = include_user_input?(args) ||
126
- dangerous_interp?(args) ||
127
- dangerous_string_building?(args)
128
128
  else
129
129
  failure = include_user_input?(args) ||
130
130
  dangerous_interp?(args) ||
@@ -176,6 +176,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
176
176
  def include_user_input? exp
177
177
  if node_type? exp, :arglist, :dstr, :evstr, :dxstr
178
178
  exp.each_sexp do |e|
179
+ next if shell_escape? e
180
+
179
181
  if res = include_user_input?(e)
180
182
  return res
181
183
  end
@@ -196,7 +198,7 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
196
198
  # Check for input at start of string
197
199
  exp[1] == "" and
198
200
  node_type? exp[2], :evstr and
199
- has_immediate_user_input? exp[2]
201
+ dangerous? exp[2]
200
202
  else
201
203
  has_immediate_user_input? exp
202
204
  end
@@ -266,6 +268,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
266
268
  end
267
269
 
268
270
  def dangerous_interp? exp
271
+ return if shell_escape? exp
272
+
269
273
  match = include_interp? exp
270
274
  return unless match
271
275
  interp = match.match
@@ -311,7 +311,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
311
311
  end
312
312
 
313
313
  if request_value? arg
314
- unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys].include? arg.method
314
+ unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys, :compact, :compact_blank].include? arg.method
315
315
  # Model.where(params[:where])
316
316
  arg
317
317
  end
@@ -645,7 +645,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
645
645
  locale_call? exp
646
646
  end
647
647
 
648
- QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
648
+ QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name, :quote_schema_name]
649
649
 
650
650
  def quote_call? exp
651
651
  if call? exp.target
@@ -258,12 +258,19 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
258
258
  #Look for "type" of render in options hash
259
259
  #For example, render :file => "blah"
260
260
  if hash? last_arg
261
- hash_iterate(last_arg) do |key, val|
262
- if symbol? key and types_in_hash.include? key.value
263
- type = key.value
264
- value = val
265
- else
266
- rest << key << val
261
+ if type
262
+ #The render type was already determined by a positional argument, so a
263
+ #key in the options hash that happens to match a render type name (e.g.
264
+ #`text:`) is a local passed to the partial/action, not a type directive.
265
+ rest = last_arg
266
+ else
267
+ hash_iterate(last_arg) do |key, val|
268
+ if symbol? key and types_in_hash.include? key.value
269
+ type = key.value
270
+ value = val
271
+ else
272
+ rest << key << val
273
+ end
267
274
  end
268
275
  end
269
276
  end
@@ -6,7 +6,7 @@ class Brakeman::GemProcessor < Brakeman::BasicProcessor
6
6
  def initialize *args
7
7
  super
8
8
  @gem_name_version = /^\s*([-_+.A-Za-z0-9]+) \((\w(\.\w+)*)\)/
9
- @ruby_version = /^\s+ruby (\d\.\d.\d+)/
9
+ @ruby_version = /^\s+ruby (\d+\.\d+\.\d+)/
10
10
  end
11
11
 
12
12
  def process_gems gem_files
@@ -186,6 +186,8 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
186
186
 
187
187
  def raw? exp
188
188
  call? exp and
189
- exp.method == :raw
189
+ exp.target.nil? and
190
+ exp.method == :raw and
191
+ exp.first_arg
190
192
  end
191
193
  end
@@ -19,7 +19,9 @@ module Brakeman::RenderHelper
19
19
  end
20
20
  when :default
21
21
  begin
22
- process_template template_name, exp[3], nil, exp.line
22
+ # exp[2] is either the action name (from controller) or :default when no explicit arg
23
+ name_arg = (exp[2].nil? || exp[2] == :default) ? nil : exp[2]
24
+ process_template template_name(name_arg), exp[3], nil, exp.line
23
25
  rescue ArgumentError
24
26
  Brakeman.debug "Problem processing render: #{exp}"
25
27
  end
@@ -187,8 +187,14 @@ class Brakeman::Scanner
187
187
  end
188
188
 
189
189
  if @app_tree.exists? ".ruby-version"
190
- if version = @app_tree.file_path(".ruby-version").read[/(\d\.\d.\d+)/]
191
- tracker.config.set_ruby_version version, @app_tree.file_path(".ruby-version"), 1
190
+ contents = @app_tree.file_path(".ruby-version").read
191
+ # Skip alternative Ruby implementations — the EOL dates Brakeman knows
192
+ # about are MRI's, so a `.ruby-version` of "jruby-10.0.2.0" should not
193
+ # be parsed as MRI 0.0.2 / 10.0.2.
194
+ unless contents =~ /\A\s*(jruby|truffleruby|rbx|rubinius|mruby)\b/i
195
+ if version = contents[/(\d+\.\d+\.\d+)/]
196
+ tracker.config.set_ruby_version version, @app_tree.file_path(".ruby-version"), 1
197
+ end
192
198
  end
193
199
  end
194
200
 
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "8.0.4"
2
+ Version = "8.0.6"
3
3
  end
data/lib/brakeman.rb CHANGED
@@ -427,7 +427,7 @@ module Brakeman
427
427
  release_date = latest.date.to_date
428
428
  latest_version = latest.version.to_s
429
429
 
430
- if (Date.today - latest.date.to_date) >= days_old
430
+ if (Date.today - release_date) >= days_old
431
431
  if current != latest_version
432
432
  return "Brakeman #{current} is not the latest version #{latest_version}"
433
433
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.4
4
+ version: 8.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Collins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-27 00:00:00.000000000 Z
11
+ date: 2026-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest