improve fix for symlink attacks to check subdirectories for symlinks too

before writing
master
joey 2006-03-29 18:50:36 +00:00
parent 2a16e15122
commit efe91335c6
4 changed files with 17 additions and 11 deletions

View File

@ -425,7 +425,7 @@ sub cgi_editpage ($$) { #{{{
my $content=$form->field('content'); my $content=$form->field('content');
$content=~s/\r\n/\n/g; $content=~s/\r\n/\n/g;
$content=~s/\r/\n/g; $content=~s/\r/\n/g;
writefile("$config{srcdir}/$file", $content); writefile($file, $config{srcdir}, $content);
my $message="web commit "; my $message="web commit ";
if (length $session->param("name")) { if (length $session->param("name")) {

View File

@ -349,7 +349,7 @@ sub render ($) { #{{{
$content=htmlize($type, $content); $content=htmlize($type, $content);
check_overwrite("$config{destdir}/".htmlpage($page), $page); check_overwrite("$config{destdir}/".htmlpage($page), $page);
writefile("$config{destdir}/".htmlpage($page), writefile(htmlpage($page), $config{destdir},
genpage($content, $page, mtime($srcfile))); genpage($content, $page, mtime($srcfile)));
$oldpagemtime{$page}=time; $oldpagemtime{$page}=time;
$renderedfiles{$page}=htmlpage($page); $renderedfiles{$page}=htmlpage($page);
@ -358,14 +358,14 @@ sub render ($) { #{{{
# check_overwrite, as above, but currently renderedfiles # check_overwrite, as above, but currently renderedfiles
# only supports listing one file per page. # only supports listing one file per page.
if ($config{rss} && exists $inlinepages{$page}) { if ($config{rss} && exists $inlinepages{$page}) {
writefile("$config{destdir}/".rsspage($page), writefile(rsspage($page), $config{destdir},
genrss($content, $page, mtime($srcfile))); genrss($content, $page, mtime($srcfile)));
} }
} }
else { else {
$links{$file}=[]; $links{$file}=[];
check_overwrite("$config{destdir}/$file", $file); check_overwrite("$config{destdir}/$file", $file);
writefile("$config{destdir}/$file", $content); writefile($file, $config{destdir}, $content);
$oldpagemtime{$file}=time; $oldpagemtime{$file}=time;
$renderedfiles{$file}=$file; $renderedfiles{$file}=$file;
} }

View File

@ -161,7 +161,8 @@ page from the web, which follows the symlink when reading the page, and
again when saving the changed page. again when saving the changed page.
This was fixed by making ikiwiki refuse to read or write to files that are 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 ## underlaydir override attacks

17
ikiwiki
View File

@ -202,15 +202,20 @@ sub readfile ($) { #{{{
return $ret; return $ret;
} #}}} } #}}}
sub writefile ($$) { #{{{ sub writefile ($$$) { #{{{
my $file=shift; my $file=shift; # can include subdirs
my $destdir=shift; # directory to put file in
my $content=shift; my $content=shift;
if (-l $file) { my $test=$file;
error("cannot write to a symlink ($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) { if (! -d $dir) {
my $d=""; my $d="";
foreach my $s (split(m!/+!, $dir)) { 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; print OUT $content;
close OUT; close OUT;
} #}}} } #}}}