Disable path traversal for Project File/Folder and added Session Switch command (#1908)

This commit is contained in:
Andreas Maerten 2023-08-02 21:38:22 +02:00 committed by GitHub
parent fa0f2b4071
commit b7b13ac638
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 4 deletions

View File

@ -0,0 +1,89 @@
#include "backend/command.hpp"
#include "util/session.hpp"
namespace big
{
class switch_session : command
{
std::unordered_map<eSessionType, const char*> m_session_types = {
{eSessionType::JOIN_PUBLIC, "PUB"},
{eSessionType::NEW_PUBLIC, "NEWPUB"},
{eSessionType::CLOSED_CREW, "CLOSEDCREW"},
{eSessionType::CREW, "NEWCREW"},
{eSessionType::CLOSED_FRIENDS, "CLOSEDFRIENDS"},
{eSessionType::FIND_FRIEND, "FRIENDS"},
{eSessionType::SOLO, "SOLO"},
{eSessionType::INVITE_ONLY, "INVITE"},
{eSessionType::JOIN_CREW, "CREW"},
{eSessionType::SC_TV, "SCTV"},
{eSessionType::LEAVE_ONLINE, "SINGLEPLAYER"},
};
using command::command;
std::string valid_args(bool was_session_string = false)
{
std::string valid_args;
if (was_session_string)
{
for (const auto& session_type_string : m_session_types | std::ranges::views::values)
{
if (!empty(valid_args))
{
valid_args += ", ";
}
valid_args += session_type_string;
}
return valid_args;
}
for (const auto& session_type_id : m_session_types | std::ranges::views::keys)
{
if (!empty(valid_args))
{
valid_args += ", ";
}
valid_args += std::to_string(static_cast<int>(session_type_id));
}
return valid_args;
}
virtual std::optional<command_arguments> parse_args(const std::vector<std::string>& args, const std::shared_ptr<command_context> ctx) override
{
command_arguments result(1);
auto sessionType = static_cast<eSessionType>(std::atoi(args[0].c_str()));
if (m_session_types.find(sessionType) == m_session_types.end())
{
ctx->report_error(std::format("Invalid session type ID given \"{}\", valid inputs are [{}].", args[0], valid_args()));
return std::nullopt;
}
if (sessionType == eSessionType::JOIN_PUBLIC && args[0] != "0")
{
const auto it = std::find_if(m_session_types.begin(), m_session_types.end(), [&args](const std::pair<eSessionType, const char*>& t) -> bool {
return t.second == args[0];
});
if (it == m_session_types.end())
{
ctx->report_error(std::format("Unknown session type \"{}\", valid inputs are [{}].", args[0], valid_args(true)));
return std::nullopt;
}
sessionType = it->first;
}
result.push<eSessionType>(sessionType);
return result;
}
virtual void execute(const command_arguments& args, const std::shared_ptr<command_context> ctx) override
{
session::join_type(args.shift<eSessionType>());
}
};
switch_session g_switch_session("joinsession", "Join Session", "Join a specific session type.", 1);
}

View File

@ -1,4 +1,4 @@
#include "backend/player_command.hpp" #include "backend/command.hpp"
#include "network/CNetworkPlayerMgr.hpp" #include "network/CNetworkPlayerMgr.hpp"
#include "pointers.hpp" #include "pointers.hpp"
#include "services/players/player_service.hpp" #include "services/players/player_service.hpp"

View File

@ -18,7 +18,9 @@ namespace big
file file_manager::get_project_file(std::filesystem::path file_path) file file_manager::get_project_file(std::filesystem::path file_path)
{ {
if (file_path.is_absolute()) if (file_path.is_absolute())
throw std::exception("Project files are relative to the BaseDir, don't use absolute paths!"); throw std::invalid_argument("Project files are relative to the BaseDir, don't use absolute paths!");
if (file_path.string().contains(".."))
throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in file paths.");
return file_manager::ensure_file_can_be_created(m_base_dir / file_path); return file_manager::ensure_file_can_be_created(m_base_dir / file_path);
} }
@ -26,7 +28,9 @@ namespace big
folder file_manager::get_project_folder(std::filesystem::path folder_path) folder file_manager::get_project_folder(std::filesystem::path folder_path)
{ {
if (folder_path.is_absolute()) if (folder_path.is_absolute())
throw std::exception("Project folders are relative to the BaseDir, don't use absolute paths!"); throw std::invalid_argument("Project folders are relative to the BaseDir, don't use absolute paths!");
if (folder_path.string().contains(".."))
throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in folder paths.");
return file_manager::ensure_folder_exists(m_base_dir / folder_path); return file_manager::ensure_folder_exists(m_base_dir / folder_path);
} }

View File

@ -12,7 +12,9 @@ namespace big
file folder::get_file(std::filesystem::path file_path) const file folder::get_file(std::filesystem::path file_path) const
{ {
if (file_path.is_absolute()) if (file_path.is_absolute())
throw std::exception("folder#get_file requires a relative path."); throw std::invalid_argument("folder#get_file requires a relative path.");
if (file_path.string().contains(".."))
throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in file paths.");
return file(m_folder_path / file_path); return file(m_folder_path / file_path);
} }