Security: fix `include` bypass of `EntryFilter#filter` symlink check (#7226)

Merge pull request 7226
This commit is contained in:
Parker Moore 2018-09-07 15:17:55 -04:00 committed by jekyllbot
parent 863a93f9ff
commit f1c87a9129
4 changed files with 69 additions and 6 deletions

View File

@ -31,7 +31,12 @@ module Jekyll
def filter(entries) def filter(entries)
entries.reject do |e| entries.reject do |e|
special?(e) || backup?(e) || excluded?(e) || symlink?(e) unless included?(e) # Reject this entry if it is a symlink.
next true if symlink?(e)
# Do not reject this entry if it is included.
next false if included?(e)
# Reject this entry if it is special, a backup file, or excluded.
special?(e) || backup?(e) || excluded?(e)
end end
end end

View File

@ -0,0 +1 @@
/etc/passwd

View File

@ -5,7 +5,7 @@ require "helper"
class TestEntryFilter < JekyllUnitTest class TestEntryFilter < JekyllUnitTest
context "Filtering entries" do context "Filtering entries" do
setup do setup do
@site = Site.new(site_configuration) @site = fixture_site
end end
should "filter entries" do should "filter entries" do
@ -87,7 +87,7 @@ class TestEntryFilter < JekyllUnitTest
# no support for symlinks on Windows # no support for symlinks on Windows
skip_if_windows "Jekyll does not currently support symlinks on Windows." skip_if_windows "Jekyll does not currently support symlinks on Windows."
site = Site.new(site_configuration("safe" => true)) site = fixture_site("safe" => true)
site.reader.read_directories("symlink-test") site.reader.read_directories("symlink-test")
assert_equal %w(main.scss symlinked-file).length, site.pages.length assert_equal %w(main.scss symlinked-file).length, site.pages.length
@ -99,11 +99,22 @@ class TestEntryFilter < JekyllUnitTest
# no support for symlinks on Windows # no support for symlinks on Windows
skip_if_windows "Jekyll does not currently support symlinks on Windows." skip_if_windows "Jekyll does not currently support symlinks on Windows."
site = Site.new(site_configuration) @site.reader.read_directories("symlink-test")
refute_equal [], @site.pages
refute_equal [], @site.static_files
end
should "include only safe symlinks in safe mode even when included" do
# no support for symlinks on Windows
skip_if_windows "Jekyll does not currently support symlinks on Windows."
site = fixture_site("safe" => true, "include" => ["symlinked-file-outside-source"])
site.reader.read_directories("symlink-test") site.reader.read_directories("symlink-test")
refute_equal [], site.pages
refute_equal [], site.static_files # rubocop:disable Performance/FixedSize
assert_equal %w(main.scss symlinked-file).length, site.pages.length
refute_includes site.static_files.map(&:name), "symlinked-file-outside-source"
# rubocop:enable Performance/FixedSize
end end
end end

View File

@ -31,5 +31,51 @@ class TestLayoutReader < JekyllUnitTest
assert_equal LayoutReader.new(@site).layout_directory, source_dir("blah/_layouts") assert_equal LayoutReader.new(@site).layout_directory, source_dir("blah/_layouts")
end end
end end
context "when a layout is a symlink" do
setup do
FileUtils.ln_sf("/etc/passwd", source_dir("_layouts", "symlink.html"))
@site = fixture_site(
"safe" => true,
"include" => ["symlink.html"]
)
end
teardown do
FileUtils.rm(source_dir("_layouts", "symlink.html"))
end
should "only read the layouts which are in the site" do
skip_if_windows "Jekyll does not currently support symlinks on Windows."
layouts = LayoutReader.new(@site).read
refute layouts.key?("symlink"), "Should not read the symlinked layout"
end
end
context "with a theme" do
setup do
FileUtils.ln_sf("/etc/passwd", theme_dir("_layouts", "theme-symlink.html"))
@site = fixture_site(
"include" => ["theme-symlink.html"],
"theme" => "test-theme",
"safe" => true
)
end
teardown do
FileUtils.rm(theme_dir("_layouts", "theme-symlink.html"))
end
should "not read a symlink'd theme" do
skip_if_windows "Jekyll does not currently support symlinks on Windows."
layouts = LayoutReader.new(@site).read
refute layouts.key?("theme-symlink"), \
"Should not read symlinked layout from theme"
end
end
end end
end end