diff --git a/example/upload.cc b/example/upload.cc index fd34e8f43a..03013843cc 100644 --- a/example/upload.cc +++ b/example/upload.cc @@ -8,6 +8,7 @@ #include #include #include + using namespace httplib; using namespace std; @@ -45,12 +46,41 @@ int main(void) { << "text file length: " << text_file.content.length() << endl << "text file name: " << text_file.filename << endl; + // Reduce a client-supplied filename to a safe base name, or return an + // empty string if it cannot be trusted (empty, ".", "..", or contains a + // path separator). + auto sanitize = [](const string &filename) -> string { + auto name = filename.substr(filename.find_last_of("/\\") + 1); + if (name.empty() || name == "." || name == ".." || + name.find(':') != string::npos) { + return string(); + } + return name; + }; + + const auto image_name = sanitize(image_file.filename); + const auto text_name = sanitize(text_file.filename); + if (image_name.empty() || text_name.empty()) { + res.status = StatusCode::BadRequest_400; + return; + } + { - ofstream ofs(image_file.filename, ios::binary); + ofstream ofs(image_name, ios::binary); + if (!ofs) { + res.status = StatusCode::InternalServerError_500; + res.set_content("Failed to write image file", "text/plain"); + return; + } ofs << image_file.content; } { - ofstream ofs(text_file.filename); + ofstream ofs(text_name); + if (!ofs) { + res.status = StatusCode::InternalServerError_500; + res.set_content("Failed to write text file", "text/plain"); + return; + } ofs << text_file.content; }