loolwsd: security: Cleanup HTTP download request

Sanitize for some funny inputs.

Change-Id: I450cb5ed6e03e9809308e8f763af2c2a66fcecb0
This commit is contained in:
Pranav Kant 2016-10-03 10:51:20 +05:30
parent 700a310d35
commit 3fa2115fa1

View file

@ -555,15 +555,8 @@ private:
{
Log::info("File download request.");
//TODO: Check that the user in question has access to this file!
const std::string dirPath = LOOLWSD::ChildRoot + tokens[3]
+ JAILED_DOCUMENT_ROOT + tokens[4];
std::string fileName;
URI::decode(tokens[5], fileName);
const std::string filePath = dirPath + "/" + fileName;
Log::info("HTTP request for: " + filePath);
File file(filePath);
// Validate the dockey
// 1. Validate the dockey
std::string decodedUri;
URI::decode(tokens[2], decodedUri);
const auto docKey = DocumentBroker::getDocKey(DocumentBroker::sanitizeURI(decodedUri));
@ -573,24 +566,55 @@ private:
{
throw BadRequestException("DocKey [" + docKey + "] is invalid.");
}
// 2. Cross-check if received child id is correct
if (docBrokerIt->second->getJailId() != tokens[3])
{
throw BadRequestException("ChildId does not correspond to docKey");
}
// 3. Don't let user download the file in main doc directory containing
// the document being edited otherwise we will end up deleting main directory
// after download finishes
if (docBrokerIt->second->getJailId() == tokens[4])
{
throw BadRequestException("RandomDir cannot be equal to ChildId");
}
docBrokersLock.unlock();
if (file.exists())
std::string fileName;
bool responded = false;
URI::decode(tokens[5], fileName);
const Path filePath(LOOLWSD::ChildRoot + tokens[3]
+ JAILED_DOCUMENT_ROOT + tokens[4] + "/" + fileName);
Log::info("HTTP request for: " + filePath.toString());
if (filePath.isAbsolute() && File(filePath).exists())
{
response.set("Access-Control-Allow-Origin", "*");
HTMLForm form(request);
const std::string mimeType = form.has("mime_type")
? form.get("mime_type")
: "application/octet-stream";
response.sendFile(filePath, mimeType);
//TODO: Cleanup on error.
Util::removeFile(dirPath, true);
return true;
try
{
response.sendFile(filePath.toString(), mimeType);
responded = true;
}
catch (const Exception& exc)
{
Log::error() << "Error sending file to client. PocoException: " << exc.displayText()
<< (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
<< Log::end;
}
Util::removeFile(File(filePath.parent()).path(), true);
}
else
{
Log::error("Download file [" + filePath + "] not found.");
Log::error("Download file [" + filePath.toString() + "] not found.");
}
return responded;
}
throw BadRequestException("Invalid or unknown request.");