From 872e318924e695420901168b2be31caea4917ef1 Mon Sep 17 00:00:00 2001 From: Greg Sutcliffe Date: Mon, 16 Jun 2014 12:54:30 +0100 Subject: [PATCH 1/1] Fixes #6086 - CVE-2014-0007 fixed TFTP boot API remote --- lib/proxy/tftp.rb | 8 +++++--- test/tftp_test.rb | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/proxy/tftp.rb b/lib/proxy/tftp.rb index de9b79f..1854156 100644 --- a/lib/proxy/tftp.rb +++ b/lib/proxy/tftp.rb @@ -98,15 +98,17 @@ module Proxy::TFTP class << self include Proxy::Util def fetch_boot_file dst, src - filename = src.split("/")[-1] - destination = Pathname.new("#{SETTINGS.tftproot}/#{dst}-#{filename}") + filename = dst + '-' + src.split("/")[-1] + destination = Pathname.new(File.absolute_path(filename, SETTINGS.tftproot)).cleanpath + tftproot = Pathname.new(SETTINGS.tftproot).cleanpath + raise "TFTP destination outside of tftproot" unless destination.to_s.start_with?(tftproot.to_s) # Ensure that our image directory exists # as the dst might contain another sub directory FileUtils.mkdir_p destination.parent wget = which("wget") - cmd = "#{wget} --timeout=10 --tries=3 --no-check-certificate -nv -c #{src} -O \"#{destination}\"" + cmd = "#{wget} --timeout=10 --tries=3 --no-check-certificate -nv -c \"#{escape_for_shell(src.to_s)}\" -O \"#{escape_for_shell(destination.to_s)}\"" CommandTask.new(cmd) end end diff --git a/test/tftp_test.rb b/test/tftp_test.rb index 8e97773..7f0cb91 100644 --- a/test/tftp_test.rb +++ b/test/tftp_test.rb @@ -22,4 +22,21 @@ class TftpTest < Test::Unit::TestCase SETTINGS.stubs(:tftproot).returns("./some/root") assert_equal Pathname.new(__FILE__).join("..", "..", "lib","proxy","some","root").to_s, @tftp.send(:path) end + + def test_paths_inside_tftp_directory_dont_raise_errors + SETTINGS.stubs(:tftproot).returns("/some/root") + Proxy::Util::CommandTask.stubs(:new).returns(true) + FileUtils.stubs(:mkdir_p).returns(true) + assert Proxy::TFTP.send(:fetch_boot_file,'/some/root/boot/file','http://localhost/file') + end + + def test_paths_outside_tftp_directory_raise_errors + SETTINGS.stubs(:tftproot).returns("/some/root") + Proxy::Util::CommandTask.stubs(:new).returns(true) + FileUtils.stubs(:mkdir_p).returns(true) + assert_raises RuntimeError do + Proxy::TFTP.send(:fetch_boot_file,'/other/root/boot/file','http://localhost/file') + end + end + end -- 1.9.3