browserstack-local 1.5.0 → 1.5.1

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: c6cc02b00944100bc4c6548ee133ad288a6c96271342c358f1c76398bad4087c
4
- data.tar.gz: 128f9be2ca356f0efff2cf5fa9e9d92d7a2e68da5430b8329c5251ee5f2b30d6
3
+ metadata.gz: e32e052d39ddb27d0c6d4e65796a8d7155896124874e6b98cb7a187f8ac2580b
4
+ data.tar.gz: a3708dc83e2be4f34aa09efb80a3a7a414449fecef23f19d2cf58db933f114fb
5
5
  SHA512:
6
- metadata.gz: 8c014452cb36ae15b6f3e2b1e3e722fa0f2b4d0fdfbaff6a8c22960072765e30942fa32a754654e7132ddc68fb6c8339adc3d6bc4ab5e41574144ef266b6ffac
7
- data.tar.gz: e6b001e4caeab902ea85c7d0c5cf0ef2f455aee7ce3b36e864b251dc43ec05dee957e44eda2e4f4592d3be464c328bfd60eff7d001c15190e6aab1920ceb2cf6
6
+ metadata.gz: dfc70f0d1c49f0aeda327cd85bb6ebdd2e920c3757cfea81098a35b1c28925d7b2c621c2b7bb630d781f9a80b8bc003feccb675958594a97b66c50e79842c76a
7
+ data.tar.gz: 21b7f15d270f6163aa930f424831f5b286ad36560416cfe602ac559c4e13ee62177824e52680aaa94f19f7c70ed0132fd13fa980e999a29da6c2ba87351cc41c
@@ -1,6 +1,7 @@
1
1
  require 'browserstack/localbinary'
2
2
  require 'browserstack/localexception'
3
3
  require 'json'
4
+ require 'fileutils'
4
5
 
5
6
  module BrowserStack
6
7
 
@@ -73,10 +74,16 @@ class Local
73
74
  @binary_path
74
75
  end
75
76
 
76
- if @is_windows
77
- system("echo > #{@logfile}")
78
- else
79
- system("echo '' > '#{@logfile}'")
77
+ # Create/truncate the logfile without a shell. The previous
78
+ # `system("echo ... > #{@logfile}")` passed @logfile to /bin/sh (or cmd.exe),
79
+ # so shell metacharacters in a caller-supplied logfile path executed as commands
80
+ # (CWE-78). File.write treats the path purely as a filename.
81
+ logfile_dir = File.dirname(@logfile)
82
+ FileUtils.mkdir_p(logfile_dir) unless File.directory?(logfile_dir)
83
+ begin
84
+ File.write(@logfile, "")
85
+ rescue SystemCallError => e
86
+ raise BrowserStack::LocalException.new("Unable to open logfile: #{e.message}")
80
87
  end
81
88
 
82
89
  if defined? spawn
@@ -121,12 +128,27 @@ class Local
121
128
  @pid = nil
122
129
  end
123
130
 
131
+ # Public accessor used by callers for debugging/logging. Return the command
132
+ # with the access key masked so it is never written to logs, CI artifacts or
133
+ # error trackers (CWE-312). The real key is still used for execution via
134
+ # start_command_args / start_command(false).
124
135
  def command
125
- start_command
136
+ start_command(true)
137
+ end
138
+
139
+ # Prevent Ruby's default #inspect from dumping @key when a Local instance is
140
+ # logged or included in an exception payload (CWE-312).
141
+ def inspect
142
+ redacted = instance_variables.map do |var|
143
+ value = var == :@key && !@key.to_s.empty? ? "[REDACTED]" : instance_variable_get(var)
144
+ "#{var}=#{value.inspect}"
145
+ end.join(", ")
146
+ "#<#{self.class}:0x#{format('%016x', object_id << 1)} #{redacted}>"
126
147
  end
127
148
 
128
- def start_command
129
- cmd = "#{@binary_path} -d start -logFile '#{@logfile}' #{@folder_flag} #{@key} #{@folder_path} #{@force_local_flag}"
149
+ def start_command(redact = false)
150
+ key = redact && !@key.to_s.empty? ? "[REDACTED]" : @key
151
+ cmd = "#{@binary_path} -d start -logFile '#{@logfile}' #{@folder_flag} #{key} #{@folder_path} #{@force_local_flag}"
130
152
  cmd += " -localIdentifier #{@local_identifier_flag}" if @local_identifier_flag
131
153
  cmd += " #{@only_flag} #{@only_automate_flag}"
132
154
  cmd += " -proxyHost #{@proxy_host}" if @proxy_host
@@ -133,7 +133,14 @@ class LocalBinary
133
133
  end
134
134
 
135
135
  def verify_binary(bin_path)
136
- binary_response = IO.popen(bin_path + " --version").readline
136
+ # Array form: exec's the binary directly, so a path containing shell
137
+ # metacharacters or spaces is never interpreted by /bin/sh (CWE-78).
138
+ #
139
+ # The scanner rule below fires on any non-static first argument to IO.popen
140
+ # and does not model the array form -- which is exactly the fix here, since
141
+ # no shell is spawned at all. Suppressed for this rule only.
142
+ # nosemgrep: ruby.lang.security.dangerous-exec.dangerous-exec
143
+ binary_response = IO.popen([bin_path, '--version']).readline
137
144
  !!(binary_response =~ /BrowserStack Local version \d+\.\d+/)
138
145
  rescue StandardError
139
146
  false
@@ -1,3 +1,3 @@
1
1
  module BrowserStack
2
- VERSION = '1.5.0'.freeze
2
+ VERSION = '1.5.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browserstack-local
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - BrowserStack