return PlatformResult(ErrorCode::NO_ERROR);
}
+namespace {
+
+PlatformResult anyFilePathContainsForbiddenSubstrings(UnZip& unzip) {
+ unsigned long irrelevant_info = 0;
+ ArchiveFileEntryPtrMapPtr entries_map = std::make_shared<ArchiveFileEntryPtrMap>();
+ auto result = unzip.listEntries(&irrelevant_info, &entries_map);
+ if (!result) {
+ LoggerE("Failed to list archive entries");
+ return result;
+ }
+
+ for (auto& file_path_and_file_info : *entries_map) {
+ const auto& file_path = file_path_and_file_info.first;
+ if (pathContainsProhibitedSubstrings(file_path)) {
+ const std::string error_msg = "File path " + file_path + " conatins a forbidden substring";
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg, ("%s", error_msg.c_str()));
+ }
+ }
+
+ return PlatformResult{ErrorCode::NO_ERROR};
+}
+
+} // namespace
+
PlatformResult ArchiveFile::extractAllTask(ExtractAllProgressCallback* callback) {
ScopeLogger();
filesystem::FilePtr directory = callback->getDirectory();
return result;
}
+ result = anyFilePathContainsForbiddenSubstrings(*unzip);
+ if (!result) {
+ return result;
+ }
+
return unzip->extractAllFilesTo(directory->getNode()->getPath()->getFullPath(), callback);
}
picojson::value v_entry_name = data.at(PARAM_NAME);
const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
+ const auto entry_path = v_entry_name.get<std::string>();
+ if (pathContainsProhibitedSubstrings(entry_path)) {
+ const std::string error_msg = "Entry path " + entry_path + " contains a prohibited substring";
+ LoggerE("%s", error_msg.c_str());
+ PostError(PlatformResult{ErrorCode::UNKNOWN_ERR, error_msg}, callbackId);
+ return;
+ }
+
const long operationId = static_cast<long>(v_op_id.get<double>());
const long handle = static_cast<long>(v_handle.get<double>());
return std::string(ss.str());
}
+bool pathContainsProhibitedSubstrings(const std::string& path) {
+ ScopeLogger("Path: %s", path.c_str());
+
+ for (const auto& prohibited_substring : kProhibitedSubstrings) {
+ if (path.find(prohibited_substring) != std::string::npos) {
+ LoggerE("Prohibited substring found: %s", prohibited_substring.c_str());
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace archive
} // namespace extension
std::string getArchiveLogMessage(const int errorCode, const std::string& hint);
+/**
+ * The API will not allow some operations on files that contain forbidden
+ * substrings in their paths. This is done to prevent path traversal attacks,
+ * i.e. extracting files to paths that the application should not access.
+ */
+const std::vector<std::string> kProhibitedSubstrings = {".."};
+bool pathContainsProhibitedSubstrings(const std::string& path);
+
} // namespace archive
} // namespace extension
// permissions would be changed after extract process would be finished,
// for now using default 0775
if (mkdir(left_part.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
- LoggerE("Couldn't create new directory: %s errno: %s", left_part.c_str(),
- GetErrorString(errno).c_str());
+ int errno_copy = errno;
+ LoggerE("Couldn't create new directory: %s errno: %d (%s)", left_part.c_str(), errno,
+ GetErrorString(errno_copy).c_str());
}
}
}