From a8dd34420b2c59c883ed070d1f2ebee346b4688b Mon Sep 17 00:00:00 2001 From: Andy Lindeman Date: Mon, 6 Jan 2014 23:39:39 -0500 Subject: [PATCH] Prevents disclosure of file existence Signed-off-by: Parker Moore --- lib/jekyll/tags/include.rb | 16 ++++++++++------ test/test_tags.rb | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb index 394d4e67..db19ed8a 100644 --- a/lib/jekyll/tags/include.rb +++ b/lib/jekyll/tags/include.rb @@ -95,13 +95,13 @@ eos end def render(context) - dir = File.join(context.registers[:site].source, INCLUDES_DIR) + dir = File.join(File.realpath(context.registers[:site].source), INCLUDES_DIR) file = render_variable(context) || @file validate_file_name(file) path = File.join(dir, file) - validate_path(path, context.registers[:site].safe) + validate_path(path, dir, context.registers[:site].safe) begin partial = Liquid::Template.parse(source(path, context)) @@ -115,14 +115,18 @@ eos end end - def validate_path(path, safe) - if !File.exist?(path) + def validate_path(path, dir, safe) + if safe && !realpath_prefixed_with?(path, dir) + raise IOError.new "The included file '#{path}' should exist and should not be a symlink" + elsif !File.exist?(path) raise IOError.new "Included file '#{path}' not found" - elsif path != File.realpath(path) && safe - raise IOError.new "The included file '#{path}' should not be a symlink" end end + def realpath_prefixed_with?(path, dir) + File.exist?(path) && File.realpath(path).start_with?(dir) + end + def blank? false end diff --git a/test/test_tags.rb b/test/test_tags.rb index 194846f1..37e1d583 100644 --- a/test/test_tags.rb +++ b/test/test_tags.rb @@ -381,6 +381,21 @@ CONTENT end assert_no_match /SYMLINK TEST/, @result end + + should "not expose the existence of symlinked files" do + ex = assert_raise IOError do + content = < 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true, 'safe' => true }) + end + assert_match /should exist and should not be a symlink/, ex.message + end end context "with one parameter" do