From f4e5e0c716585b072b5a401602f7847272ae5d4a Mon Sep 17 00:00:00 2001 From: Rylan Polster Date: Sat, 13 Jul 2024 14:39:53 -0400 Subject: [PATCH] Don't allow special characters in sandbox rule paths Co-authored-by: Thierry Moisan --- Library/Homebrew/sandbox.rb | 26 ++++++++++------ Library/Homebrew/test/sandbox_spec.rb | 44 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/Library/Homebrew/sandbox.rb b/Library/Homebrew/sandbox.rb index 0cbd7db525..ee612c67b4 100644 --- a/Library/Homebrew/sandbox.rb +++ b/Library/Homebrew/sandbox.rb @@ -231,6 +231,22 @@ class Sandbox end end + # @api private + sig { params(path: T.any(String, Pathname), type: Symbol).returns(String) } + def path_filter(path, type) + invalid_char = ['"', "'", "(", ")", "\n"].find do |c| + path.to_s.include?(c) + end + raise ArgumentError, "Invalid character #{invalid_char} in path: #{path}" if invalid_char + + case type + when :regex then "regex #\"#{path}\"" + when :subpath then "subpath \"#{expand_realpath(Pathname.new(path))}\"" + when :literal then "literal \"#{expand_realpath(Pathname.new(path))}\"" + else raise ArgumentError, "Invalid path filter type: #{type}" + end + end + private sig { params(path: Pathname).returns(Pathname) } @@ -240,16 +256,6 @@ class Sandbox path.exist? ? path.realpath : expand_realpath(path.parent)/path.basename end - sig { params(path: T.any(String, Pathname), type: Symbol).returns(String) } - def path_filter(path, type) - case type - when :regex then "regex #\"#{path}\"" - when :subpath then "subpath \"#{expand_realpath(Pathname.new(path))}\"" - when :literal then "literal \"#{expand_realpath(Pathname.new(path))}\"" - else raise ArgumentError, "Invalid path filter type: #{type}" - end - end - class SandboxRule sig { returns(T::Boolean) } attr_reader :allow diff --git a/Library/Homebrew/test/sandbox_spec.rb b/Library/Homebrew/test/sandbox_spec.rb index 79845beaa2..a68c7efecd 100644 --- a/Library/Homebrew/test/sandbox_spec.rb +++ b/Library/Homebrew/test/sandbox_spec.rb @@ -21,6 +21,50 @@ RSpec.describe Sandbox, :needs_macos do expect(file).to exist end + describe "#path_filter" do + ["'", '"', "(", ")", "\n"].each do |char| + it "fails if the path contains #{char}" do + expect do + sandbox.path_filter("foo#{char}bar", :subpath) + end.to raise_error(ArgumentError) + end + end + end + + describe "#allow_write_cellar" do + it "fails when the formula has a name including )" do + f = formula do + url "https://brew.sh/foo-1.0.tar.gz" + version "1.0" + + def initialize(*, **) + super + @name = "foo)bar" + end + end + + expect do + sandbox.allow_write_cellar f + end.to raise_error(ArgumentError) + end + + it "fails when the formula has a name including \"" do + f = formula do + url "https://brew.sh/foo-1.0.tar.gz" + version "1.0" + + def initialize(*, **) + super + @name = "foo\"bar" + end + end + + expect do + sandbox.allow_write_cellar f + end.to raise_error(ArgumentError) + end + end + describe "#exec" do it "fails when writing to file not specified with ##allow_write" do expect do