Module: OllamaAgent::PathSandbox
- Defined in:
- lib/ollama_agent/path_sandbox.rb
Overview
Resolves paths under a project root using File.realpath so symlinks cannot escape the sandbox.
Class Method Summary collapse
- .allowed?(root_abs, root_real, user_path) ⇒ Boolean
- .candidate_under_root?(expanded_abs, root_real, root_abs) ⇒ Boolean
- .lexically_under_root_abs?(expanded_abs, root_abs) ⇒ Boolean
-
.nonexistent_path_allowed_under_root?(expanded_abs, root_real, root_abs) ⇒ Boolean
rubocop:disable Metrics/MethodLength – parent walk for missing path segments.
- .under_root_real?(path_real, root_real) ⇒ Boolean
Class Method Details
.allowed?(root_abs, root_real, user_path) ⇒ Boolean
13 14 15 16 17 18 19 20 |
# File 'lib/ollama_agent/path_sandbox.rb', line 13 def allowed?(root_abs, root_real, user_path) return false if user_path.nil? || user_path.to_s.strip.empty? = Pathname(user_path.to_s).(root_abs).cleanpath.to_s return false unless lexically_under_root_abs?(, root_abs) candidate_under_root?(, root_real, root_abs) end |
.candidate_under_root?(expanded_abs, root_real, root_abs) ⇒ Boolean
26 27 28 29 30 31 32 33 |
# File 'lib/ollama_agent/path_sandbox.rb', line 26 def candidate_under_root?(, root_real, root_abs) path_real = File.realpath() under_root_real?(path_real, root_real) rescue Errno::ENOENT nonexistent_path_allowed_under_root?(, root_real, root_abs) rescue Errno::ELOOP, Errno::EACCES false end |
.lexically_under_root_abs?(expanded_abs, root_abs) ⇒ Boolean
22 23 24 |
# File 'lib/ollama_agent/path_sandbox.rb', line 22 def lexically_under_root_abs?(, root_abs) == root_abs || .start_with?(root_abs + File::SEPARATOR) end |
.nonexistent_path_allowed_under_root?(expanded_abs, root_real, root_abs) ⇒ Boolean
rubocop:disable Metrics/MethodLength – parent walk for missing path segments
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ollama_agent/path_sandbox.rb', line 40 def nonexistent_path_allowed_under_root?(, root_real, root_abs) parent = loop do next_parent = File.dirname(parent) break if next_parent == parent parent = next_parent begin pr = File.realpath(parent) return false unless under_root_real?(pr, root_real) return lexically_under_root_abs?(, root_abs) rescue Errno::ENOENT next rescue Errno::ELOOP, Errno::EACCES return false end end false end |
.under_root_real?(path_real, root_real) ⇒ Boolean
35 36 37 |
# File 'lib/ollama_agent/path_sandbox.rb', line 35 def under_root_real?(path_real, root_real) path_real == root_real || path_real.start_with?(root_real + File::SEPARATOR) end |