Class: LanguageOperator::Agent::Safety::SafeExecutor::SandboxProxy
- Inherits:
- BasicObject
- Defined in:
- lib/language_operator/agent/safety/safe_executor.rb
Overview
Proxy class that wraps the context and intercepts method calls
Instance Method Summary collapse
-
#const_missing(name) ⇒ Object
Provide access to safe constants from the context.
-
#initialize(context, executor) ⇒ SandboxProxy
constructor
A new instance of SandboxProxy.
-
#method_missing(method_name, *args) ⇒ Object
Delegate method calls to the underlying context but check for dangerous methods first.
- #respond_to_missing?(method_name, include_private = false) ⇒ Boolean
Constructor Details
#initialize(context, executor) ⇒ SandboxProxy
Returns a new instance of SandboxProxy.
78 79 80 81 |
# File 'lib/language_operator/agent/safety/safe_executor.rb', line 78 def initialize(context, executor) @__context__ = context @__executor__ = executor end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args) ⇒ Object
Delegate method calls to the underlying context but check for dangerous methods first
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/language_operator/agent/safety/safe_executor.rb', line 85 def method_missing(method_name, *args, &) # Log the call @__executor__.log_call(@__context__, method_name, args) # Special handling for require - allow only 'language_operator' if %i[require require_relative].include?(method_name) required_gem = args.first.to_s return ::Kernel.require(required_gem) if required_gem == 'language_operator' # Allow require 'language_operator' ::Kernel.raise ::LanguageOperator::Agent::Safety::SafeExecutor::SecurityError, "Require '#{required_gem}' is not allowed. Only 'require \"language_operator\"' is permitted." end # Check if method is safe unless safe_method?(method_name) ::Kernel.raise ::LanguageOperator::Agent::Safety::SafeExecutor::SecurityError, "Method '#{method_name}' is not allowed in sandboxed code" end # Delegate to underlying context @__context__.send(method_name, *args, &) end |
Instance Method Details
#const_missing(name) ⇒ Object
Provide access to safe constants from the context
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/language_operator/agent/safety/safe_executor.rb', line 116 def const_missing(name) # Define allowed constants explicitly (security-by-default) # This allowlist must be kept in sync with ASTValidator safe constants case name when :HTTP ::LanguageOperator::Dsl::HTTP when :Shell ::LanguageOperator::Dsl::Shell when :String, :Array, :Hash, :Integer, :Float, :Numeric, :Symbol # Allow safe Ruby built-in types ::Object.const_get(name) when :Time, :Date # Allow safe time/date types ::Object.const_get(name) when :TrueClass, :FalseClass, :NilClass # Allow boolean and nil types ::Object.const_get(name) when :ArgumentError, :TypeError, :RuntimeError, :StandardError # Allow standard Ruby exception classes for error handling ::Object.const_get(name) else # Security-by-default: explicitly deny access to any other constants # This prevents sandbox bypass through const_missing fallback ::Kernel.raise ::LanguageOperator::Agent::Safety::SafeExecutor::SecurityError, "Access to constant '#{name}' is not allowed in sandbox (security restriction)" end end |
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
111 112 113 |
# File 'lib/language_operator/agent/safety/safe_executor.rb', line 111 def respond_to_missing?(method_name, include_private = false) @__context__.respond_to?(method_name, include_private) end |