2010-03-08 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Ignore filename parameter if it contains directory traversal
	directives.
	* src/util.cc
	* test/UtilTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-03-07 15:06:48 +00:00
parent 41b7b9428f
commit 3ecf6e4b6f
3 changed files with 36 additions and 26 deletions

View File

@ -1,3 +1,10 @@
2010-03-08 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Ignore filename parameter if it contains directory traversal
directives.
* src/util.cc
* test/UtilTest.cc
2010-03-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
urldecode -> percentDecode

View File

@ -656,18 +656,6 @@ void parsePrioritizePieceRange
result.insert(result.end(), indexes.begin(), indexes.end());
}
static std::string trimBasename(const std::string& src)
{
static const std::string TRIMMED("\r\n\t '\"");
std::string fn = File(trim(src, TRIMMED)).getBasename();
std::string::iterator enditer = std::remove(fn.begin(), fn.end(), '\\');
fn = std::string(fn.begin(), enditer);
if(fn == ".." || fn == A2STR::DOT_C) {
fn = A2STR::NIL;
}
return fn;
}
// Converts ISO/IEC 8859-1 string to UTF-8 string. If there is a
// character not in ISO/IEC 8859-1, returns empty string.
std::string iso8859ToUtf8(const std::string& src)
@ -759,12 +747,17 @@ std::string getContentDispositionFilename(const std::string& header)
if(bad) {
continue;
}
value = trimBasename(percentDecode(value));
value = percentDecode(value);
if(toLower(extValues[0]) == "iso-8859-1") {
value = iso8859ToUtf8(value);
}
filename = value;
break;
if(!detectDirTraversal(value) &&
value.find(A2STR::SLASH_C) == std::string::npos) {
filename = value;
}
if(!filename.empty()) {
break;
}
} else {
for(; markeritr != param.end() && *markeritr == ' '; ++markeritr);
if(markeritr == param.end() || *markeritr != '=') {
@ -785,9 +778,14 @@ std::string getContentDispositionFilename(const std::string& header)
} else {
filenameLast = value.end();
}
value =
trimBasename(percentDecode(std::string(value.begin(), filenameLast)));
filename = value;
static const std::string TRIMMED("\r\n\t '\"");
value = percentDecode(std::string(value.begin(), filenameLast));
trimSelf(value, TRIMMED);
value.erase(std::remove(value.begin(), value.end(), '\\'), value.end());
if(!detectDirTraversal(value) &&
value.find(A2STR::SLASH_C) == std::string::npos) {
filename = value;
}
// continue because there is a chance we can find filename*=...
}
}

View File

@ -307,16 +307,12 @@ void UtilTest::testGetContentDispositionFilename() {
CPPUNIT_ASSERT_EQUAL(std::string(""), util::getContentDispositionFilename(h11));
std::string filenameWithDir = "attachment; filename=dir/file";
CPPUNIT_ASSERT_EQUAL(std::string("file"),
CPPUNIT_ASSERT_EQUAL(std::string(""),
util::getContentDispositionFilename(filenameWithDir));
CPPUNIT_ASSERT_EQUAL
(std::string(""),
util::getContentDispositionFilename("filename=\"%2E%2E%2Ffoo.html\""));
std::string parentDir = "attachment; filename=..";
CPPUNIT_ASSERT_EQUAL(std::string(),
util::getContentDispositionFilename(parentDir));
std::string currentDir = "attachment; filename=.";
CPPUNIT_ASSERT_EQUAL(std::string(),
util::getContentDispositionFilename(currentDir));
// RFC2231 Section4
std::string extparam2 = "filename*=''aria2";
CPPUNIT_ASSERT_EQUAL(std::string("aria2"),
@ -345,6 +341,15 @@ void UtilTest::testGetContentDispositionFilename() {
extparam9ans += 0xa3;
CPPUNIT_ASSERT_EQUAL(extparam9ans,
util::getContentDispositionFilename(extparam9));
CPPUNIT_ASSERT_EQUAL
(std::string(""),
util::getContentDispositionFilename("filename*=UTF-8''foo%2F.html"));
CPPUNIT_ASSERT_EQUAL
(std::string("foo.html"),
util::getContentDispositionFilename("filename*=UTF-8'';filename=\"foo.html\""));
CPPUNIT_ASSERT_EQUAL
(std::string(""),
util::getContentDispositionFilename("filename*=UTF-8''%2E%2E%2Ffoo.html"));
// Tests from http://greenbytes.de/tech/tc2231/
// attwithasciifnescapedchar