Skip to content
This repository has been archived by the owner on Mar 5, 2024. It is now read-only.

Commit

Permalink
Added a more robust log message filtering method that should prevent …
Browse files Browse the repository at this point in the history
…the users's steam api key from being recorded to the log file or output to the app log in any circumstances.
  • Loading branch information
PazerOP committed Aug 16, 2020
1 parent 8d03717 commit 4743cb3
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 32 deletions.
17 changes: 14 additions & 3 deletions tf2_bot_detector/Config/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ namespace tf2_bot_detector
}
}

void GeneralSettings::SetSteamAPIKey(std::string key)
{
ILogManager::GetInstance().AddSecret(key, mh::format("<STEAM_API_KEY:{}>", key.size()));
m_SteamAPIKey = std::move(key);
}

void tf2_bot_detector::to_json(nlohmann::json& j, const ProgramUpdateCheckMode& d)
{
switch (d)
Expand Down Expand Up @@ -202,14 +208,13 @@ void Settings::LoadFile()

if (auto found = json.find("general"); found != json.end())
{
constexpr GeneralSettings DEFAULTS;
static const GeneralSettings DEFAULTS;

try_get_to_defaulted(*found, m_LocalSteamIDOverride, "local_steamid_override");
try_get_to_defaulted(*found, m_SleepWhenUnfocused, "sleep_when_unfocused");
try_get_to_defaulted(*found, m_AutoTempMute, "auto_temp_mute", DEFAULTS.m_AutoTempMute);
try_get_to_defaulted(*found, m_AllowInternetUsage, "allow_internet_usage");
try_get_to_defaulted(*found, m_ProgramUpdateCheckMode, "program_update_check_mode", DEFAULTS.m_ProgramUpdateCheckMode);
try_get_to_defaulted(*found, m_SteamAPIKey, "steam_api_key");
try_get_to_defaulted(*found, m_AutoLaunchTF2, "auto_launch_tf2", DEFAULTS.m_AutoLaunchTF2);
try_get_to_defaulted(*found, m_AutoChatWarnings, "auto_chat_warnings", DEFAULTS.m_AutoChatWarnings);
try_get_to_defaulted(*found, m_AutoChatWarningsConnecting, "auto_chat_warnings_connecting", DEFAULTS.m_AutoChatWarningsConnecting);
Expand All @@ -218,6 +223,12 @@ void Settings::LoadFile()
try_get_to_defaulted(*found, m_AutoMark, "auto_mark", DEFAULTS.m_AutoMark);
try_get_to_defaulted(*found, m_LazyLoadAPIData, "lazy_load_api_data", DEFAULTS.m_LazyLoadAPIData);

{
std::string apiKey;
try_get_to_defaulted(*found, apiKey, "steam_api_key");
SetSteamAPIKey(std::move(apiKey));
}

if (auto foundDir = found->find("steam_dir_override"); foundDir != found->end())
m_SteamDirOverride = foundDir->get<std::string_view>();
if (auto foundDir = found->find("tf_game_dir_override"); foundDir != found->end())
Expand Down Expand Up @@ -248,7 +259,7 @@ bool Settings::SaveFile() const
{ "sleep_when_unfocused", m_SleepWhenUnfocused },
{ "auto_temp_mute", m_AutoTempMute },
{ "program_update_check_mode", m_ProgramUpdateCheckMode },
{ "steam_api_key", m_SteamAPIKey },
{ "steam_api_key", GetSteamAPIKey() },
{ "auto_launch_tf2", m_AutoLaunchTF2 },
{ "auto_chat_warnings", m_AutoChatWarnings },
{ "auto_chat_warnings_connecting", m_AutoChatWarningsConnecting },
Expand Down
8 changes: 6 additions & 2 deletions tf2_bot_detector/Config/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ namespace tf2_bot_detector
ProgramUpdateCheckMode m_ProgramUpdateCheckMode = ProgramUpdateCheckMode::Unknown;

constexpr auto GetAutoVotekickDelay() const { return std::chrono::duration<float>(m_AutoVotekickDelay); }

const std::string& GetSteamAPIKey() const { return m_SteamAPIKey; }
void SetSteamAPIKey(std::string key);

private:
std::string m_SteamAPIKey;
};

class Settings final : public AutoDetectedSettings, public GeneralSettings
Expand All @@ -91,8 +97,6 @@ namespace tf2_bot_detector

} m_Unsaved;

std::string m_SteamAPIKey;

std::optional<bool> m_AllowInternetUsage;
const HTTPClient* GetHTTPClient() const;

Expand Down
59 changes: 56 additions & 3 deletions tf2_bot_detector/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <imgui.h>
#include <mh/text/format.hpp>
#include <mh/text/string_insertion.hpp>
#include <mh/text/stringops.hpp>

#include <deque>
#include <filesystem>
Expand Down Expand Up @@ -32,7 +33,7 @@ namespace
LogManager& operator=(const LogManager&) = delete;

void Log(std::string msg, const LogMessageColor& color = {}, time_point_t timestamp = clock_t::now()) override;
void LogToStream(const std::string_view& msg, std::ostream& output, time_point_t timestamp = clock_t::now()) const;
void LogToStream(std::string msg, std::ostream& output, time_point_t timestamp = clock_t::now(), bool skipScrub = false) const;

const std::filesystem::path& GetFileName() const override { return m_FileName; }
cppcoro::generator<const LogMessage&> GetVisibleMsgs() const override;
Expand All @@ -44,13 +45,23 @@ namespace

void CleanupLogFiles() override;

void AddSecret(std::string value, std::string replace) override;

private:
std::filesystem::path m_FileName;
std::ofstream m_File;
mutable std::recursive_mutex m_LogMutex;
std::deque<LogMessage> m_LogMessages;
size_t m_VisibleLogMessagesStart = 0;

struct Secret
{
std::string m_Value;
std::string m_Replacement;
};
std::vector<Secret> m_Secrets;
void ReplaceSecrets(std::string& str) const;

static constexpr size_t MAX_LOG_MESSAGES = 500;

mutable std::recursive_mutex m_ConsoleLogMutex;
Expand Down Expand Up @@ -120,10 +131,13 @@ LogManager::LogManager()
}
}

void LogManager::LogToStream(const std::string_view& msg, std::ostream& output, time_point_t timestamp) const
void LogManager::LogToStream(std::string msg, std::ostream& output, time_point_t timestamp, bool skipScrub) const
{
std::lock_guard lock(m_LogMutex);

if (!skipScrub)
ReplaceSecrets(msg);

tm t = ToTM(timestamp);
const auto WriteToStream = [&](std::ostream& str)
{
Expand All @@ -142,7 +156,9 @@ void LogManager::LogToStream(const std::string_view& msg, std::ostream& output,
void LogManager::Log(std::string msg, const LogMessageColor& color, time_point_t timestamp)
{
std::lock_guard lock(m_LogMutex);
LogToStream(msg, m_File, timestamp);

ReplaceSecrets(msg);
LogToStream(msg, m_File, timestamp, true);
m_LogMessages.push_back({ timestamp, std::move(msg), { color.r, color.g, color.b, color.a } });

if (m_LogMessages.size() > MAX_LOG_MESSAGES)
Expand All @@ -152,6 +168,43 @@ void LogManager::Log(std::string msg, const LogMessageColor& color, time_point_t
}
}

void LogManager::AddSecret(std::string value, std::string replace)
{
if (value.empty())
return;

std::lock_guard lock(m_LogMutex);
for (auto& scrubbed : m_Secrets)
{
if (scrubbed.m_Value == value)
{
scrubbed.m_Replacement = std::move(replace);
return;
}
}

m_Secrets.push_back(Secret
{
.m_Value = std::move(value),
.m_Replacement = std::move(replace)
});
}

void LogManager::ReplaceSecrets(std::string& msg) const
{
std::lock_guard lock(m_LogMutex);
for (const auto& scrubbed : m_Secrets)
{
size_t index = msg.find(scrubbed.m_Value);
while (index != msg.npos)
{
msg.erase(index, scrubbed.m_Value.size());
msg.insert(index, scrubbed.m_Replacement);
index = msg.find(scrubbed.m_Value, index + scrubbed.m_Replacement.size());
}
}
}

namespace
{
template<typename CharT, typename Traits>
Expand Down
2 changes: 2 additions & 0 deletions tf2_bot_detector/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,7 @@ namespace tf2_bot_detector
virtual void LogConsoleOutput(const std::string_view& consoleOutput) = 0;

virtual void CleanupLogFiles() = 0;

virtual void AddSecret(std::string value, std::string replace) = 0;
};
}
5 changes: 2 additions & 3 deletions tf2_bot_detector/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ MainWindow::MainWindow() :
{
m_TextureManager = CreateTextureManager();


ILogManager::GetInstance().CleanupLogFiles();

m_WorldState.AddConsoleLineListener(this);
Expand Down Expand Up @@ -964,10 +963,10 @@ void MainWindow::OnDrawSettingsPopup()
ImGui::EnabledSwitch(m_Settings.m_AllowInternetUsage.value_or(false), [&](bool enabled)
{
ImGui::NewLine();
if (std::string key = m_Settings.m_SteamAPIKey;
if (std::string key = m_Settings.GetSteamAPIKey();
InputTextSteamAPIKey("Steam API Key", key, true))
{
m_Settings.m_SteamAPIKey = key;
m_Settings.SetSteamAPIKey(key);
m_Settings.SaveFile();
}
ImGui::NewLine();
Expand Down
14 changes: 1 addition & 13 deletions tf2_bot_detector/Networking/SteamAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,7 @@ namespace
auto clientPtr = client.shared_from_this();
return s_SteamAPIThreadPool.add_task([clientPtr, url]() -> SteamAPITask
{
static const std::regex s_Regex(R"regex([?&]key=([0-9a-fA-F]*))regex", std::regex::optimize);
{
auto urlCopy = url;
if (std::smatch result; std::regex_search(urlCopy.m_Path, result, s_Regex))
{
const size_t startPos = result[1].first - urlCopy.m_Path.begin();
const auto length = result[1].length();
urlCopy.m_Path.erase(startPos, length);
urlCopy.m_Path.insert(startPos, mh::fmtstr<64>("<KEY:{}>", length));
}

DebugLog("[SteamAPI] HTTP GET "s << urlCopy);
}
DebugLog("[SteamAPI] HTTP GET "s << url);

SteamAPITask retVal;
retVal.m_RequestURL = url;
Expand Down
16 changes: 8 additions & 8 deletions tf2_bot_detector/WorldState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ void WorldState::Update()
void WorldState::UpdateFriends()
{
if (auto client = m_Settings->GetHTTPClient();
client && !m_Settings->m_SteamAPIKey.empty() && (clock_t::now() - 5min) > m_LastFriendsUpdate)
client && !m_Settings->GetSteamAPIKey().empty() && (clock_t::now() - 5min) > m_LastFriendsUpdate)
{
m_LastFriendsUpdate = clock_t::now();
m_FriendsFuture = SteamAPI::GetFriendList(m_Settings->m_SteamAPIKey, m_Settings->GetLocalSteamID(), *client);
m_FriendsFuture = SteamAPI::GetFriendList(m_Settings->GetSteamAPIKey(), m_Settings->GetLocalSteamID(), *client);
}

if (mh::is_future_ready(m_FriendsFuture))
Expand Down Expand Up @@ -719,13 +719,13 @@ const SteamAPI::TF2PlaytimeResult* WorldState::PlayerExtraData::GetTF2Playtime()
{
if (!m_TF2PlaytimeFetched)
{
if (!m_World->m_Settings->m_SteamAPIKey.empty())
if (!m_World->m_Settings->GetSteamAPIKey().empty())
{
if (auto client = m_World->m_Settings->GetHTTPClient())
{
m_TF2PlaytimeFetched = true;
m_TF2Playtime = SteamAPI::GetTF2PlaytimeAsync(
m_World->m_Settings->m_SteamAPIKey, GetSteamID(), *client);
m_World->m_Settings->GetSteamAPIKey(), GetSteamID(), *client);
}
}
}
Expand Down Expand Up @@ -814,13 +814,13 @@ auto WorldState::PlayerSummaryUpdateAction::SendRequest(
if (!client)
return {};

if (state->m_Settings->m_SteamAPIKey.empty())
if (state->m_Settings->GetSteamAPIKey().empty())
return {};

std::vector<SteamID> steamIDs = Take100(collection);

return SteamAPI::GetPlayerSummariesAsync(
state->m_Settings->m_SteamAPIKey, std::move(steamIDs), *client);
state->m_Settings->GetSteamAPIKey(), std::move(steamIDs), *client);
}

void WorldState::PlayerSummaryUpdateAction::OnDataReady(WorldState*& state,
Expand All @@ -841,12 +841,12 @@ auto WorldState::PlayerBansUpdateAction::SendRequest(state_type& state,
if (!client)
return {};

if (state->m_Settings->m_SteamAPIKey.empty())
if (state->m_Settings->GetSteamAPIKey().empty())
return {};

std::vector<SteamID> steamIDs = Take100(collection);
return SteamAPI::GetPlayerBansAsync(
state->m_Settings->m_SteamAPIKey, std::move(steamIDs), *client);
state->m_Settings->GetSteamAPIKey(), std::move(steamIDs), *client);
}

void WorldState::PlayerBansUpdateAction::OnDataReady(state_type& state,
Expand Down

0 comments on commit 4743cb3

Please sign in to comment.