Skip to content
Permalink
Browse files Browse the repository at this point in the history
Don't allow extraction of tar files outside of the target directory, …
…added tar tests
  • Loading branch information
jcoffland committed Jul 19, 2020
1 parent 71a999a commit 1c1dba6
Show file tree
Hide file tree
Showing 21 changed files with 99 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/cbang/tar/TarFileReader.cpp
Expand Up @@ -101,11 +101,26 @@ std::string TarFileReader::extract(const string &_path) {
if (!hasMore()) THROW("No more tar files");

string path = _path;
if (SystemUtilities::isDirectory(path)) path += "/" + getFilename();
if (SystemUtilities::isDirectory(path)) {
path += "/" + getFilename();

// Check that path is under the target directory
string a = SystemUtilities::getCanonicalPath(_path);
string b = SystemUtilities::getCanonicalPath(path);
if (!String::startsWith(b, a))
THROW("Tar path points outside of the extraction directory: " << path);
}

LOG_DEBUG(5, "Extracting: " << path);

return extract(*SystemUtilities::oopen(path));
switch (getType()) {
case NORMAL_FILE: case CONTIGUOUS_FILE:
return extract(*SystemUtilities::oopen(path));
case DIRECTORY: SystemUtilities::ensureDirectory(path); break;
default: THROW("Unsupported tar file type " << getType());
}

return getFilename();
}


Expand Down
1 change: 1 addition & 0 deletions tests/tarTests/.gitignore
@@ -0,0 +1 @@
/path
1 change: 1 addition & 0 deletions tests/tarTests/BadExtractTest/data/args
@@ -0,0 +1 @@
--extract test.tar
Binary file added tests/tarTests/BadExtractTest/data/test.tar
Binary file not shown.
1 change: 1 addition & 0 deletions tests/tarTests/BadExtractTest/expect/return
@@ -0,0 +1 @@
1
1 change: 1 addition & 0 deletions tests/tarTests/BadExtractTest/expect/stderr
@@ -0,0 +1 @@
Tar path points outside of the extraction directory: ./../hello.txt
Empty file.
1 change: 1 addition & 0 deletions tests/tarTests/CompressedExtractTest/data/args
@@ -0,0 +1 @@
--extract test.tar.bz2
Binary file not shown.
1 change: 1 addition & 0 deletions tests/tarTests/CompressedExtractTest/expect/return
@@ -0,0 +1 @@
0
Empty file.
1 change: 1 addition & 0 deletions tests/tarTests/CompressedExtractTest/expect/stdout
@@ -0,0 +1 @@
hello.txt
1 change: 1 addition & 0 deletions tests/tarTests/ExtractTest/data/args
@@ -0,0 +1 @@
--extract test.tar
Binary file added tests/tarTests/ExtractTest/data/test.tar
Binary file not shown.
1 change: 1 addition & 0 deletions tests/tarTests/ExtractTest/expect/return
@@ -0,0 +1 @@
0
Empty file.
1 change: 1 addition & 0 deletions tests/tarTests/ExtractTest/expect/stdout
@@ -0,0 +1 @@
hello.txt
8 changes: 8 additions & 0 deletions tests/tarTests/SConscript
@@ -0,0 +1,8 @@
Import('*')

# Local includes
env.Append(CPPPATH = ['#'])

prog = env.Program('tar', 'tar.cpp')

Return('prog')
Binary file added tests/tarTests/tar
Binary file not shown.
61 changes: 61 additions & 0 deletions tests/tarTests/tar.cpp
@@ -0,0 +1,61 @@
/******************************************************************************\
This file is part of the C! library. A.K.A the cbang library.
Copyright (c) 2003-2019, Cauldron Development LLC
Copyright (c) 2003-2017, Stanford University
All rights reserved.
The C! library is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 2.1 of
the License, or (at your option) any later version.
The C! library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the C! library. If not, see
<http://www.gnu.org/licenses/>.
In addition, BSD licensing may be granted on a case by case basis
by written permission from at least one of the copyright holders.
You may request written permission by emailing the authors.
For information regarding this software email:
Joseph Coffland
joseph@cauldrondevelopment.com
\******************************************************************************/

#include <cbang/tar/TarFileReader.h>
#include <cbang/Catch.h>

#include <iostream>

using namespace cb;
using namespace std;


int main(int argc, char *argv[]) {
try {
for (int i = 1; i < argc; i++) {
string arg = argv[i];

if (arg == "--extract" && i < argc - 1) {
TarFileReader reader(argv[++i]);

while (reader.hasMore())
cout << reader.extract() << endl;

} else THROWS("Invalid arg '" << arg << "'");
}

return 0;

} catch (const Exception &e) {cerr << e.getMessage();}

return 1;
}
3 changes: 3 additions & 0 deletions tests/tarTests/test.json
@@ -0,0 +1,3 @@
{
"command": "%(suite-dir)s/tar"
}

0 comments on commit 1c1dba6

Please sign in to comment.