From efe91335c65b96f3eb8b32d8c58c9cce68db47b4 Mon Sep 17 00:00:00 2001 From: joey Date: Wed, 29 Mar 2006 18:50:36 +0000 Subject: [PATCH] improve fix for symlink attacks to check subdirectories for symlinks too before writing --- IkiWiki/CGI.pm | 2 +- IkiWiki/Render.pm | 6 +++--- doc/security.mdwn | 3 ++- ikiwiki | 17 +++++++++++------ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm index b47c8e803..f360b6778 100644 --- a/IkiWiki/CGI.pm +++ b/IkiWiki/CGI.pm @@ -425,7 +425,7 @@ sub cgi_editpage ($$) { #{{{ my $content=$form->field('content'); $content=~s/\r\n/\n/g; $content=~s/\r/\n/g; - writefile("$config{srcdir}/$file", $content); + writefile($file, $config{srcdir}, $content); my $message="web commit "; if (length $session->param("name")) { diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index 3d827d341..9e340c26e 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -349,7 +349,7 @@ sub render ($) { #{{{ $content=htmlize($type, $content); check_overwrite("$config{destdir}/".htmlpage($page), $page); - writefile("$config{destdir}/".htmlpage($page), + writefile(htmlpage($page), $config{destdir}, genpage($content, $page, mtime($srcfile))); $oldpagemtime{$page}=time; $renderedfiles{$page}=htmlpage($page); @@ -358,14 +358,14 @@ sub render ($) { #{{{ # check_overwrite, as above, but currently renderedfiles # only supports listing one file per page. if ($config{rss} && exists $inlinepages{$page}) { - writefile("$config{destdir}/".rsspage($page), + writefile(rsspage($page), $config{destdir}, genrss($content, $page, mtime($srcfile))); } } else { $links{$file}=[]; check_overwrite("$config{destdir}/$file", $file); - writefile("$config{destdir}/$file", $content); + writefile($file, $config{destdir}, $content); $oldpagemtime{$file}=time; $renderedfiles{$file}=$file; } diff --git a/doc/security.mdwn b/doc/security.mdwn index 0f8861d0d..3743adea1 100644 --- a/doc/security.mdwn +++ b/doc/security.mdwn @@ -161,7 +161,8 @@ page from the web, which follows the symlink when reading the page, and again when saving the changed page. This was fixed by making ikiwiki refuse to read or write to files that are -symlinks, combined with the above locking. +symlinks, or that are in subdirectories that are symlinks, combined with +the above locking. ## underlaydir override attacks diff --git a/ikiwiki b/ikiwiki index 4ef6ceba3..b1bc9984f 100755 --- a/ikiwiki +++ b/ikiwiki @@ -202,15 +202,20 @@ sub readfile ($) { #{{{ return $ret; } #}}} -sub writefile ($$) { #{{{ - my $file=shift; +sub writefile ($$$) { #{{{ + my $file=shift; # can include subdirs + my $destdir=shift; # directory to put file in my $content=shift; - if (-l $file) { - error("cannot write to a symlink ($file)"); + my $test=$file; + while (length $test) { + if (-l "$destdir/$test") { + error("cannot write to a symlink ($test)"); + } + $test=dirname($test); } - my $dir=dirname($file); + my $dir=dirname("$destdir/$file"); if (! -d $dir) { my $d=""; foreach my $s (split(m!/+!, $dir)) { @@ -221,7 +226,7 @@ sub writefile ($$) { #{{{ } } - open (OUT, ">$file") || error("failed to write $file: $!"); + open (OUT, ">$destdir/$file") || error("failed to write $destdir/$file: $!"); print OUT $content; close OUT; } #}}} -- 2.44.0