Ruby code to check if a pathname is contained within another pathname (e.g. "/foo/bar/baz" within "/foo/bar") without being tricked by "..". Written with @olleolleolle.
class PathnameExtras | |
def self.in_dir?(path, dir:) | |
path_parts = path.expand_path.each_filename.to_a | |
dir_parts = dir.expand_path.each_filename.to_a | |
return false if path_parts == dir_paths | |
dir_parts.zip(path_parts).all? { |x, y| x == y } | |
end | |
end |
require "spec_helper" | |
require "pathname_extras" | |
RSpec.describe PathnameExtras do | |
describe "in_dir?" do | |
it "is true when within the given dir" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo/bar/baz"), dir: Pathname("/foo/bar")) | |
expect(actual).to be true | |
end | |
it "is true when within the given dir while using '..'" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo/../foo/bar/../bar/baz"), dir: Pathname("/foo/bar")) | |
expect(actual).to be true | |
end | |
it "is true when within the given dir while the dir uses '..'" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo/bar/baz"), dir: Pathname("/foo/../foo/bar/../bar")) | |
expect(actual).to be true | |
end | |
it "is false for an already-expanded path not within the given dir" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo/bar/baz"), dir: Pathname("/boink")) | |
expect(actual).to be false | |
end | |
it "is false for a path using '..' that is not within the given dir" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo/bar/../not_bar/baz"), dir: Pathname("/foo/bar")) | |
expect(actual).to be false | |
end | |
it "is false if only dir name prefixes match" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo/bar/../bar_not/baz"), dir: Pathname("/foo/bar")) | |
expect(actual).to be false | |
end | |
it "is false if the path is a parent of the dir" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo"), dir: Pathname("/foo/bar")) | |
expect(actual).to be false | |
end | |
it "is false with no overlap whatsoever" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo"), dir: Pathname("/bar")) | |
expect(actual).to be false | |
end | |
it "is false for identical paths" do | |
actual = PathnameExtras.in_dir?(Pathname("/foo"), dir: Pathname("/foo")) | |
expect(actual).to be false | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
We considered just checking for the substring ".." but weren't confident this would protect against all forms of traversal. Perhaps there's some way to escape your way around it that would trick such a substring check, but not this Pathname check – not sure (we overdesigned for somewhere it wasn't strictly needed so haven't done deep research).