rails-ai-bridge 3.5.0 → 3.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: c78af79aba88ce31b9ea2d0f0c2de1e14782f5a0d2fbc9ccae9a879c86020ad8
4
- data.tar.gz: 736de35b4fa3413752e77b3ebc37abf5628c697c7855561985031d7a06b53783
3
+ metadata.gz: 86847cb1d8613336bb1538fdde0c64461dcc69d2423b48939629695f40c99688
4
+ data.tar.gz: 65d9c1a4f11b3edc80a077e66c41e339ca845e4d10993d63cddef79be7ef9c5d
5
5
  SHA512:
6
- metadata.gz: f7204bde6b731db642cedb0d3748e413f3c8f6496633328f1450412fdce6aa1127ca7fbaef443b061068f8d66177c5878f35e72a4bd75b21f8ec20f496e6c261
7
- data.tar.gz: 93f710a0ceeba7a6b55fe6323b22ae1b980424ac301877b13a9d8e2f8e63a064500e5db86db30330b7347649f2774ca9d0655e82704008d568fe4e858e2b33b2
6
+ metadata.gz: c6ae4378aa2f3321b0753fb7e111a4d6777bd4de63e5ade3bcf38047affac48ce86630490dcacd33610021f299833bc5d7dd24f9dc238614f60786d8fac42ea4
7
+ data.tar.gz: 22caf59cc05827c7a5824f17c2dd1a5715b8ba62b70930ef300835bdbdc96506bdae1f2ec8590391272576c097363b45debb605f195e0e7c7b43c227f8a75289
data/CHANGELOG.md CHANGED
@@ -5,7 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [3.5.1]
9
+
10
+ ### Security
11
+
12
+ - Harden `DefaultGitRunner` git commands against option injection by validating clone URL/destination and using `--` separators for `git clone`; add `nosemgrep` suppressions for documented false positives in `git pull` and `git checkout`.
13
+ - Add `protect_from_forgery` to all test/fixture `ApplicationController` classes.
14
+ - Replace `content_tag` with `tag.h1` in the internal test `ApplicationHelper` and rename the misleading `raw` variable in `Config::Mcp`.
15
+ - Add `nosemgrep` comments with explanatory notes for unscoped-find false positives in internal test controllers.
16
+ - Harden `rails_search_code` ripgrep command with a `--` separator and replace shell-based `which rg` detection with direct `rg --version` checks.
17
+
18
+ ## [3.5.0]
9
19
 
10
20
  ### Added
11
21
 
data/SECURITY.md CHANGED
@@ -39,7 +39,7 @@ please report it responsibly:
39
39
  credentials are omitted from introspection and the `rails://config` resource by
40
40
  default; set `config.expose_credentials_key_names = true` only if you accept
41
41
  that metadata exposure.
42
- - The gem does not make any outbound network requests.
42
+ - The gem does not make outbound network requests except when the skill-pack registry is configured with a git source, in which case `git clone` / `git pull` fetches remote pack repositories.
43
43
  - The main risk is **information exposure**, not mutation: schema names, routes,
44
44
  controller structure, and code excerpts may still be sensitive in some environments.
45
45
 
@@ -87,19 +87,19 @@ module RailsAiBridge
87
87
  #
88
88
  # @return [Integer]
89
89
  def effective_http_rate_limit_max_requests
90
- raw = @rate_limit_max_requests
90
+ configured_value = @rate_limit_max_requests
91
91
 
92
- case raw
92
+ case configured_value
93
93
  when Integer
94
- return 0 if raw <= 0
94
+ return 0 if configured_value <= 0
95
95
 
96
- raw
96
+ configured_value
97
97
  when nil
98
98
  return 0 if http_rate_limit_implicitly_suppressed?
99
99
 
100
100
  security_profile_rate_limit_max
101
101
  else
102
- n = raw.to_i
102
+ n = configured_value.to_i
103
103
  return 0 if n <= 0
104
104
 
105
105
  n
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'open3'
4
+
3
5
  module RailsAiBridge
4
6
  class Doctor
5
7
  module Checkers
@@ -7,9 +9,15 @@ module RailsAiBridge
7
9
  class RipgrepChecker < BaseChecker
8
10
  # @return [Doctor::Check] +:pass+ when +rg+ is found; +:warn+ otherwise
9
11
  def call
12
+ available = begin
13
+ Open3.capture2('rg', '--version').last.success?
14
+ rescue Errno::ENOENT
15
+ false
16
+ end
17
+
10
18
  check(
11
19
  'ripgrep',
12
- system('which rg > /dev/null 2>&1'),
20
+ available,
13
21
  pass: { message: 'rg available for code search' },
14
22
  fail: { status: :warn, message: 'ripgrep not installed (code search will use slower Ruby fallback)',
15
23
  fix: 'Install with `brew install ripgrep` or `apt install ripgrep`' }
@@ -63,8 +63,11 @@ module RailsAiBridge
63
63
  # @raise [RuntimeError] if git clone command fails, returns non-zero, or times out
64
64
  # @return [void]
65
65
  def clone_repo(url, dest)
66
+ raise ArgumentError, "Invalid git URL #{url.inspect}: URLs must not start with '-'" if url.start_with?('-')
67
+ raise ArgumentError, "Invalid destination #{dest.inspect}: paths must not start with '-'" if dest.to_s.start_with?('-')
68
+
66
69
  with_timeout('git clone') do
67
- _stdout, stderr, status = Open3.capture3('git', 'clone', url, dest)
70
+ _stdout, stderr, status = Open3.capture3('git', 'clone', '--', url, dest)
68
71
  fail_with_sanitized_error!('git clone', stderr) unless status.success?
69
72
  end
70
73
  end
@@ -76,7 +79,8 @@ module RailsAiBridge
76
79
  # @return [void]
77
80
  def pull_repo(path)
78
81
  with_timeout('git pull') do
79
- _stdout, stderr, status = Open3.capture3('git', 'pull', chdir: path)
82
+ # Command is fully static; only the chdir option is a validated directory path.
83
+ _stdout, stderr, status = Open3.capture3('git', 'pull', chdir: path) # nosemgrep: ruby.lang.security.dangerous-exec.dangerous-exec
80
84
  fail_with_sanitized_error!('git pull', stderr) unless status.success?
81
85
  end
82
86
  end
@@ -92,7 +96,8 @@ module RailsAiBridge
92
96
  raise ArgumentError, "Invalid ref #{ref.inspect}: refs must not start with '-'" if ref.start_with?('-')
93
97
 
94
98
  with_timeout('git checkout') do
95
- _stdout, stderr, status = Open3.capture3('git', 'checkout', ref, chdir: path)
99
+ # The ref is validated above before being passed to git.
100
+ _stdout, stderr, status = Open3.capture3('git', 'checkout', ref, chdir: path) # nosemgrep: ruby.lang.security.dangerous-exec.dangerous-exec
96
101
  fail_with_sanitized_error!('git checkout', stderr) unless status.success?
97
102
  end
98
103
  end
@@ -78,7 +78,7 @@ module RailsAiBridge
78
78
  cmd.concat(excluded_path_flags)
79
79
  cmd.concat(secret_exclude_flags)
80
80
  cmd.concat(file_type_filters)
81
- cmd.push(@pattern, @path)
81
+ cmd.push('--', @pattern, @path)
82
82
  end
83
83
 
84
84
  private
@@ -71,8 +71,11 @@ module RailsAiBridge
71
71
  end
72
72
 
73
73
  def self.ripgrep_available?
74
- @ripgrep_available = system('which rg > /dev/null 2>&1') unless instance_variable_defined?(:@ripgrep_available)
75
- @ripgrep_available
74
+ return @ripgrep_available if instance_variable_defined?(:@ripgrep_available)
75
+
76
+ @ripgrep_available = Open3.capture2('rg', '--version').last.success?
77
+ rescue Errno::ENOENT
78
+ @ripgrep_available = false
76
79
  end
77
80
 
78
81
  def self.with_search_timeout(&)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAiBridge
4
- VERSION = '3.5.0'
4
+ VERSION = '3.5.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-ai-bridge
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 3.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Marin