Item9053: Move attachment results in Taint error
Priority: Urgent
Current State: Closed
Released In: 1.1.0
Target Release: minor
Moving an attachment to the Trash web results in a Taint error:
Attachment move failed
During move of attachment userdata.xml to Trash.TrashAttachment an error was found. Please notify your Foswiki administrator.
Insecure dependency in rename while running with -T switch at /usr/lib/perl5/5.10.1/File/Copy.pm line 271. at /usr/lib/perl5/5.10.1/File/Copy.pm line 271 File::Copy::move('/var/www/SVN/foswiki/core/pub/System/AttachContentPlugin/user...', '/var/www/SVN/foswiki/core/pub/Trash/TrashAttachment/userdata.xml')
called at /var/www/SVN/foswiki/core/lib/Foswiki/Store/VC/Handler.pm line 809 Foswiki::Store::VC::Handler::moveFile('Foswiki::Store::VC::RcsWrapHandler=HASH(0x873ab30)', '/var/www/SVN/foswiki/core/pub/System/AttachContentPlugin/user...', '/var/www/SVN/foswiki/core/pub/Trash/TrashAttachment/userdata.xml')
called at /var/www/SVN/foswiki/core/lib/Foswiki/Store/VC/Handler.pm line 602 Foswiki::Store::VC::Handler::moveAttachment('Foswiki::Store::VC::RcsWrapHandler=HASH(0x873ab30)', 'Foswiki::Store::RcsWrap=HASH(0x8557110)', 'Trash', 'TrashAttachment', 'userdata.xml')
called at /var/www/SVN/foswiki/core/lib/Foswiki/Store/VC/Store.pm line 151 Foswiki::Store::VC::Store::moveAttachment('Foswiki::Store::RcsWrap=HASH(0x8557110)', 'Foswiki::Meta=HASH(0x8741010)', 'userdata.xml', 'Foswiki::Meta=HASH(0x873aca0)', 'userdata.xml', 'BaseUserMapping_333')
called at /var/www/SVN/foswiki/core/lib/Foswiki/Meta.pm line 2556 Foswiki::Meta::__ANON__()
called at /var/www/SVN/foswiki/core/lib/CPAN/lib//Error.pm line 379 eval {...}
called at /var/www/SVN/foswiki/core/lib/CPAN/lib//Error.pm line 371 Error::subs::try('CODE(0x8849780)', 'HASH(0x88610e0)')
called at /var/www/SVN/foswiki/core/lib/Foswiki/Meta.pm line 2593 Foswiki::Meta::moveAttachment('Foswiki::Meta=HASH(0x8741010)', 'userdata.xml', 'Foswiki::Meta=HASH(0x873aca0)', 'new_name', 'userdata.xml')
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI/Rename.pm line 738 Foswiki::UI::Rename::__ANON__()
called at /var/www/SVN/foswiki/core/lib/CPAN/lib//Error.pm line 379 eval {...}
called at /var/www/SVN/foswiki/core/lib/CPAN/lib//Error.pm line 371 Error::subs::try('CODE(0x873ad70)', 'HASH(0x873ae50)')
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI/Rename.pm line 749 Foswiki::UI::Rename::_moveTopicOrAttachment('Foswiki=HASH(0x854f9c8)', 'Foswiki::Meta=HASH(0x8741010)', 'Foswiki::Meta=HASH(0x873aca0)', 'userdata.xml', 'userdata.xml', undef)
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI/Rename.pm line 262 Foswiki::UI::Rename::_renameTopicOrAttachment('Foswiki=HASH(0x854f9c8)', 'System', 'AttachContentPlugin')
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI/Rename.pm line 66 Foswiki::UI::Rename::rename('Foswiki=HASH(0x854f9c8)')
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI.pm line 310 Foswiki::UI::__ANON__()
called at /var/www/SVN/foswiki/core/lib/CPAN/lib//Error.pm line 379 eval {...}
called at /var/www/SVN/foswiki/core/lib/CPAN/lib//Error.pm line 371 Error::subs::try('CODE(0x85434e8)', 'HASH(0x854f6f8)')
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI.pm line 427 Foswiki::UI::_execute('Foswiki::Request=HASH(0x8431bf0)', 'CODE(0x8431780)', 'rename', 1)
called at /var/www/SVN/foswiki/core/lib/Foswiki/UI.pm line 277 Foswiki::UI::handleRequest('Foswiki::Request=HASH(0x8431bf0)')
called at /var/www/SVN/foswiki/core/lib/Foswiki/Engine/CGI.pm line 30 Foswiki::Engine::CGI::run('Foswiki::Engine::CGI=HASH(0x81e2bd8)') called
Please go back in your browser and try again.
--
GeorgeClark - 24 May 2010
See also:
Item9027
--
PaulHarvey - 24 May 2010
It would be nice if we could get these taint errors in the unit tests. But
Unit::Request
does not taint its data like CGI does.
I wrote a little method to call
Assert::TAINT()
recursively on all members (param, action, method, etc) in
new
of
Unit::Request
, but that didn't affect the unit test results (for
RegisterTests anyway).
Then I began implementing all of
Foswiki::Request
accessor methods to ensure values were tainted there, and I started getting failures in
FuncUsersTest.
So my point is, we should make sure
Unit::Request
taints everything like a real
Foswiki::Request
does in order for us to better catch these errors.
--
PaulHarvey - 24 May 2010
Were is the best place to find and untaint the various fields in Meta. It seems as though wherever I untaint, it isn't enough and errors still occur. Untaint when Meta object is created doesn't seem to help at all. And untainting in the function that triggered the error just moves the problem.
Also, should we use the Sandbox untaint functions down in core, or is there a preferred way to do the untainting?
--
GeorgeClark - 24 May 2010
This was the recursive taint I mentioned
diff --git a/UnitTestContrib/lib/Unit/Request.pm b/UnitTestContrib/lib/Unit/Request.pm
index 8606879..1d0b878 100644
--- a/UnitTestContrib/lib/Unit/Request.pm
+++ b/UnitTestContrib/lib/Unit/Request.pm
@@ -13,6 +13,50 @@ package Unit::Request;
use Foswiki::Request;
our @ISA = qw( Foswiki::Request );
+sub _taint_recursively {
+ my ($element) = @_;
+ my $ref = ref $element;
+
+ Assert::TAINT($element);
+ if ($ref eq 'HASH') {
+ foreach my $item (%$element) {
+ print '%';
+ _taint_recursively($item);
+ }
+ } elsif ($ref eq 'ARRAY') {
+ foreach my $item (@$element) {
+ print '@';
+ _taint_recursively($item);
+ }
+ }
+
+ return;
+}
+
+sub new {
+ my $this = shift;
+ $this = $this->SUPER::new(@_);
+ _taint_recursively($this->{action});
+ _taint_recursively($this->{base_action});
+ _taint_recursively($this->{cookies});
+ _taint_recursively($this->{handle});
+ _taint_recursively($this->{headers});
+ _taint_recursively($this->{http});
+ _taint_recursively($this->{method});
+ _taint_recursively($this->{param_list});
+ _taint_recursively($this->{param});
+ _taint_recursively($this->{path_info});
+ _taint_recursively($this->{protocol});
+ _taint_recursively($this->{remote_address});
+ _taint_recursively($this->{remote_user});
+ _taint_recursively($this->{secure});
+ _taint_recursively($this->{server_port});
+ _taint_recursively($this->{uploads});
+ _taint_recursively($this->{uri});
+
+ return $this;
+}
+
sub setUrl {
my ( $this, $queryString ) = @_;
--
PaulHarvey - 24 May 2010
I've applied your changes to Unit::Request - it doesn't seem to make any difference on what tests fail with taint errors. With or without your changes when running Func tests, the following test failure occurs when perl -T is used to run the test:
FuncTests::test_subweb_attachments
Insecure dependency in open while running with -T switch at /var/www/SVN/foswiki/core/lib/Foswiki/Store/VC/Handler.pm line 778.
And that particular test already forces a TAINT of the attachment filename.
--
GeorgeClark - 25 May 2010
Crawford, The fixes still missed one case - The attachment name was tainted when retrieving the version information. Following patch (already checked in) resolved the issue:
Index: /var/www/SVN/foswiki/core/lib/Foswiki/Attach.pm
===================================================================
--- /var/www/SVN/foswiki/core/lib/Foswiki/Attach.pm (revision 7550)
+++ /var/www/SVN/foswiki/core/lib/Foswiki/Attach.pm (working copy)
@@ -110,6 +110,8 @@
my ( $this, $topicObject, %attrs ) = @_;
my $users = $this->{session}->{users};
+ # SMELL: This was needed to avoid a taint error. Foswikitask:Item9053
+ $attrs{name} = Foswiki::Sandbox::normalizeFileName( $attrs{name} );
my $revIt = $topicObject->getRevisionHistory( $attrs{name} );
my $templates = $this->{session}->templates;
--
GeorgeClark - 26 May 2010
Fine. BTW that's not a SMELL. A SMELL is a piece of code that needs review and further attention. I would say that bit of code was perfectly reasonable though I might have preferred to see an untain call that validated the parameter)
--
CrawfordCurrie - 26 May 2010