From 62f1f9732b746a84a1fd3ee67b70f7a297fcdb42 Mon Sep 17 00:00:00 2001 From: joey Date: Thu, 23 Mar 2006 04:33:35 +0000 Subject: [PATCH] found & fixed another symlink attack --- doc/security.mdwn | 20 ++++++++++++++++++-- ikiwiki | 10 +++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/doc/security.mdwn b/doc/security.mdwn index 63d140ec5..c7a6fcd69 100644 --- a/doc/security.mdwn +++ b/doc/security.mdwn @@ -141,6 +141,22 @@ into the repo. ikiwiki uses File::Find to traverse the repo, and does not tell it to follow symlinks, but it might be possible to race replacing a directory with a symlink and trick it into following the link. -Also, if someone checks in a symlink to /etc/passwd, ikiwiki would read and publish that, which could be used to expose files a committer otherwise wouldn't see. +Also, if someone checks in a symlink to /etc/passwd, ikiwiki would read and +publish that, which could be used to expose files a committer otherwise +wouldn't see. -To avoid this, ikiwiki will avoid reading files that are symlinks, and uses locking to prevent more than one instance running at a time. The lock prevents one ikiwiki from running a svn up at the wrong time to race another ikiwiki. So only attackers who can write to the working copy on their own can race it. +To avoid this, ikiwiki will skip over symlinks when scanning for pages, and +uses locking to prevent more than one instance running at a time. The lock +prevents one ikiwiki from running a svn up at the wrong time to race +another ikiwiki. So only attackers who can write to the working copy on +their own can race it. + +## symlink + cgi attacks + +Similarly, a svn commit of a symlink could be made, ikiwiki ignores it +because of the above, but the symlink is still there, and then you edit the +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. diff --git a/ikiwiki b/ikiwiki index 78aa65ce2..6b8a51535 100755 --- a/ikiwiki +++ b/ikiwiki @@ -152,6 +152,10 @@ sub htmlpage ($) { #{{{ sub readfile ($) { #{{{ my $file=shift; + if (-l $file) { + error("cannot read a symlink ($file)"); + } + local $/=undef; open (IN, "$file") || error("failed to read $file: $!"); my $ret=; @@ -162,6 +166,10 @@ sub readfile ($) { #{{{ sub writefile ($$) { #{{{ my $file=shift; my $content=shift; + + if (-l $file) { + error("cannot write to a symlink ($file)"); + } my $dir=dirname($file); if (! -d $dir) { @@ -1334,7 +1342,7 @@ sub cgi_editpage ($$) { #{{{ ! length $form->field('content')) { my $content=""; if (exists $pagesources{lc($page)}) { - $content=readfile("$config{srcdir}/$pagesources{lc($page)}"); + $content=readfile("$config{srcdir}/$pagesources{lc($page)}"); $content=~s/\n/\r\n/g; } $form->field(name => "content", value => $content, -- 2.26.2