Class: Chocomint::Security::PathGuard
- Inherits:
-
Object
- Object
- Chocomint::Security::PathGuard
- Defined in:
- lib/chocomint/security/path_guard.rb
Overview
許可ディレクトリ配下のみアクセスを許し、パストラバーサルを防ぐ (DESIGN §13)。
Instance Attribute Summary collapse
-
#allowed_roots ⇒ Object
readonly
Returns the value of attribute allowed_roots.
-
#base_dir ⇒ Object
readonly
Returns the value of attribute base_dir.
Instance Method Summary collapse
-
#allowed?(path) ⇒ Boolean
例外を投げずに許可判定だけ行う。.
-
#initialize(allowed_dirs, base_dir: Dir.pwd) ⇒ PathGuard
constructor
A new instance of PathGuard.
-
#resolve(path) ⇒ Object
検証済み絶対パスを返す。許可外なら PathAccessError。.
-
#validate_args!(args) ⇒ Object
run_command / shell の引数トークン列を検査する。ファイル系ツールと違い外部 プロセスは cwd (=base_dir) 配下で好き放題できてしまうため、引数に現れる 「パスらしいトークン」が allowed_roots 内に収まるかだけ事前に確認する。 過剰検知を避けるため、パス判定はスラッシュ/バックスラッシュを含むか ".." を 含むトークンに限る (venv / pandas / init のような非パス引数は素通しする)。 許可外を指すトークンがあれば PathAccessError。.
Constructor Details
#initialize(allowed_dirs, base_dir: Dir.pwd) ⇒ PathGuard
Returns a new instance of PathGuard.
11 12 13 14 15 16 |
# File 'lib/chocomint/security/path_guard.rb', line 11 def initialize(allowed_dirs, base_dir: Dir.pwd) @base_dir = File.(base_dir) @allowed_roots = Array(allowed_dirs).map do |d| File.(d, @base_dir) end end |
Instance Attribute Details
#allowed_roots ⇒ Object (readonly)
Returns the value of attribute allowed_roots.
9 10 11 |
# File 'lib/chocomint/security/path_guard.rb', line 9 def allowed_roots @allowed_roots end |
#base_dir ⇒ Object (readonly)
Returns the value of attribute base_dir.
9 10 11 |
# File 'lib/chocomint/security/path_guard.rb', line 9 def base_dir @base_dir end |
Instance Method Details
#allowed?(path) ⇒ Boolean
例外を投げずに許可判定だけ行う。
19 20 21 22 23 24 |
# File 'lib/chocomint/security/path_guard.rb', line 19 def allowed?(path) resolve(path) true rescue PathAccessError false end |
#resolve(path) ⇒ Object
検証済み絶対パスを返す。許可外なら PathAccessError。
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/chocomint/security/path_guard.rb', line 27 def resolve(path) raise PathAccessError, "path is required" if path.nil? || path.to_s.empty? abs = File.(path.to_s, @base_dir) unless @allowed_roots.any? { |root| under?(root, abs) } raise PathAccessError, "access denied: #{path} is outside allowed directories" end abs end |
#validate_args!(args) ⇒ Object
run_command / shell の引数トークン列を検査する。ファイル系ツールと違い外部 プロセスは cwd (=base_dir) 配下で好き放題できてしまうため、引数に現れる 「パスらしいトークン」が allowed_roots 内に収まるかだけ事前に確認する。 過剰検知を避けるため、パス判定はスラッシュ/バックスラッシュを含むか ".." を 含むトークンに限る (venv / pandas / init のような非パス引数は素通しする)。 許可外を指すトークンがあれば PathAccessError。
44 45 46 47 48 49 50 51 52 |
# File 'lib/chocomint/security/path_guard.rb', line 44 def validate_args!(args) Array(args).each do |token| value = extract_path_value(token.to_s) next unless value && path_like?(value) resolve(value) # 許可外なら PathAccessError を送出 end true end |