summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-02-27 08:22:58 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-02-27 08:22:58 +0000
commitdc2a51b54a5ef934109edd8416f82a0e050657b2 (patch)
treece8eb40d47c96432f47cd72cdc98198aaae43e80 /src
parent513a6bd12dcbbb14e67a6a7b44fe77bfdef30318 (diff)
2010-02-27 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Discard torrent file if path data in it contains directory traversal directives. Discard metalink:file element in Metalink3 format if its name attribute contains directory traversal directives. Ignore name attribute of metalink:signature element in Metalink3 format if it contains directory traversal directives. * src/MetalinkParserStateV3Impl.cc * src/bittorrent_helper.cc * src/message.h * test/BittorrentHelperTest.cc * test/Makefile.am * test/MetalinkProcessorTest.cc * test/metalink3-dirtraversal.xml * test/test.xml
Diffstat (limited to 'src')
-rw-r--r--src/MetalinkParserStateV3Impl.cc11
-rw-r--r--src/bittorrent_helper.cc35
-rw-r--r--src/message.h1
3 files changed, 26 insertions, 21 deletions
diff --git a/src/MetalinkParserStateV3Impl.cc b/src/MetalinkParserStateV3Impl.cc
index dd850442..33fb1309 100644
--- a/src/MetalinkParserStateV3Impl.cc
+++ b/src/MetalinkParserStateV3Impl.cc
@@ -113,8 +113,12 @@ void FilesMetalinkParserState::beginElement
stm->setFileState();
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, NAME);
if(itr != attrs.end()) {
+ std::string name = util::trim((*itr).value);
+ if(util::detectDirTraversal(name)) {
+ return;
+ }
stm->newEntryTransaction();
- stm->setFileNameOfEntry(util::trim((*itr).value));
+ stm->setFileNameOfEntry(name);
}
} else {
stm->setSkipTagState();
@@ -275,7 +279,10 @@ void VerificationMetalinkParserState::beginElement
stm->setTypeOfSignature(util::trim((*itr).value));
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, FILE);
if(itr != attrs.end()) {
- stm->setFileOfSignature(util::trim((*itr).value));
+ std::string file = util::trim((*itr).value);
+ if(!util::detectDirTraversal(file)) {
+ stm->setFileOfSignature(file);
+ }
}
}
} else {
diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc
index fc8a3b49..73bb434b 100644
--- a/src/bittorrent_helper.cc
+++ b/src/bittorrent_helper.cc
@@ -200,19 +200,18 @@ static void extractFileEntries
}
const BDE& nameData = infoDict[nameKey];
if(nameData.isString()) {
- // Split path by '/' just in case nasty ".." is included in name
- std::vector<std::string> pathelems;
- util::split(nameData.s(), std::back_inserter(pathelems), "/");
- name = util::joinPath(pathelems.begin(), pathelems.end());
- torrent[NAME] = nameData.s();
+ if(util::detectDirTraversal(nameData.s())) {
+ throw DL_ABORT_EX
+ (StringFormat(MSG_DIR_TRAVERSAL_DETECTED,nameData.s().c_str()).str());
+ }
+ name = nameData.s();
} else {
name = strconcat(File(defaultName).getBasename(), ".file");
- torrent[NAME] = name;
}
} else {
name = overrideName;
- torrent[NAME] = name;
}
+ torrent[NAME] = name;
const BDE& filesList = infoDict[C_FILES];
std::vector<SharedHandle<FileEntry> > fileEntries;
@@ -246,17 +245,15 @@ static void extractFileEntries
throw DL_ABORT_EX("Path is empty.");
}
- std::vector<std::string> pathelem(pathList.size());
- std::transform(pathList.listBegin(), pathList.listEnd(), pathelem.begin(),
- std::mem_fun_ref(&BDE::s));
- std::string path = name;
- strappend(path, "/", util::joinPath(pathelem.begin(), pathelem.end()));
- // Split path with '/' again because each pathList element can
- // contain "/" inside.
- std::vector<std::string> elements;
- util::split(path, std::back_inserter(elements), "/");
- path = util::joinPath(elements.begin(), elements.end());
-
+ std::vector<std::string> pathelem(pathList.size()+1);
+ pathelem[0] = name;
+ std::transform(pathList.listBegin(), pathList.listEnd(),
+ pathelem.begin()+1, std::mem_fun_ref(&BDE::s));
+ std::string path = strjoin(pathelem.begin(), pathelem.end(), '/');
+ if(util::detectDirTraversal(path)) {
+ throw DL_ABORT_EX
+ (StringFormat(MSG_DIR_TRAVERSAL_DETECTED, path.c_str()).str());
+ }
std::deque<std::string> uris;
createUri(urlList.begin(), urlList.end(), std::back_inserter(uris), path);
SharedHandle<FileEntry> fileEntry
@@ -282,7 +279,7 @@ static void extractFileEntries
std::deque<std::string> uris;
for(std::vector<std::string>::const_iterator i = urlList.begin();
i != urlList.end(); ++i) {
- if(util::endsWith(*i, "/")) {
+ if(util::endsWith(*i, A2STR::SLASH_C)) {
uris.push_back((*i)+name);
} else {
uris.push_back(*i);
diff --git a/src/message.h b/src/message.h
index 930e4139..c563c2b3 100644
--- a/src/message.h
+++ b/src/message.h
@@ -180,6 +180,7 @@
#define MSG_METADATA_SAVED _("Saved metadata as %s.")
#define MSG_METADATA_NOT_SAVED _("Saving metadata as %s failed. Maybe file" \
" already exists.")
+#define MSG_DIR_TRAVERSAL_DETECTED _("Detected directory traversal directive in %s")
#define EX_TIME_OUT _("Timeout.")
#define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.")