diff options
author | joey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071> | 2006-03-29 18:50:36 +0000 |
---|---|---|
committer | joey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071> | 2006-03-29 18:50:36 +0000 |
commit | efe91335c65b96f3eb8b32d8c58c9cce68db47b4 (patch) | |
tree | 252c7b1a8af828b09e34c4d549975b71ca41831d | |
parent | 2a16e15122574cca9c5b52ccfc46a022a71e25dc (diff) | |
download | ikiwiki-efe91335c65b96f3eb8b32d8c58c9cce68db47b4.tar ikiwiki-efe91335c65b96f3eb8b32d8c58c9cce68db47b4.tar.gz |
improve fix for symlink attacks to check subdirectories for symlinks too
before writing
-rw-r--r-- | IkiWiki/CGI.pm | 2 | ||||
-rw-r--r-- | IkiWiki/Render.pm | 6 | ||||
-rw-r--r-- | doc/security.mdwn | 3 | ||||
-rwxr-xr-x | 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 @@ -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; } #}}} |