From da89d390ea60caca67a591d2cdf6f84036b27da9 Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Thu, 8 Jul 2021 14:58:03 -0700 Subject: [PATCH] :hammer: using str_intrusion.h to write to private string data --- include/bank_api.h | 1 + include/str_intrusion.h | 5 ++++ include/user_filter.h | 1 + src/bank_api.cpp | 55 ++++++++++++++++++++--------------------- src/str_intrusion.cpp | 44 +++++++++++++++++++++++++++++++++ src/user_filter.cpp | 16 ++++++------ 6 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 include/str_intrusion.h create mode 100644 src/str_intrusion.cpp diff --git a/include/bank_api.h b/include/bank_api.h index 3a46459..d10046e 100644 --- a/include/bank_api.h +++ b/include/bank_api.h @@ -1,6 +1,7 @@ #pragma once #include #include "simdjson.h" +#include "str_intrusion.h" #include "json_filter.h" #include "user_filter.h" diff --git a/include/str_intrusion.h b/include/str_intrusion.h new file mode 100644 index 0000000..8622f4e --- /dev/null +++ b/include/str_intrusion.h @@ -0,0 +1,5 @@ +#pragma once +#include + +void string_view_to_string(std::string &str, std::string_view sv); +void destroy_string(std::string &str); \ No newline at end of file diff --git a/include/user_filter.h b/include/user_filter.h index dcdea16..938bbe2 100644 --- a/include/user_filter.h +++ b/include/user_filter.h @@ -2,6 +2,7 @@ #include #include #include +#include "str_intrusion.h" #include "bank.h" using namespace drogon; diff --git a/src/bank_api.cpp b/src/bank_api.cpp index 1f61983..c757793 100644 --- a/src/bank_api.cpp +++ b/src/bank_api.cpp @@ -65,9 +65,9 @@ void api::SendFunds(req_args) const } else { - static thread_local auto &name_val = name.value(); - *(char *)(name_val.data() + name_val.size()) = '\0'; //ignoring read-only - res = bank.SendFunds(NAME_PARAM, name_val.data(), amount.value()); + static thread_local std::string name_val; + string_view_to_string(name_val, name.value()); + res = bank.SendFunds(NAME_PARAM, name_val, amount.value()); } RESPONSE_PARSE(std::move(res)); } @@ -86,9 +86,9 @@ void api::ChangePassword(req_args) const } else { - static thread_local auto &pass_val = pass.value(); - *(char *)(pass_val.data() + pass_val.size()) = '\0'; //ignoring read-only - bank.ChangePassword(NAME_PARAM, std::move(pass_val.data())); + static thread_local std::string pass_val; + string_view_to_string(pass_val, pass.value()); + bank.ChangePassword(NAME_PARAM, std::move(pass_val)); } RESPOND_TRUE; } @@ -104,10 +104,10 @@ void api::AdminChangePassword(req_args) const } else { - static thread_local auto &name_val = name.value(); - static thread_local auto &pass_val = name.value(); - *(char *)(name_val.data() + name_val.size()) = *(char *)(pass_val.data() + pass_val.size()) = '\0'; //ignoring read-only - bank.ChangePassword(name_val.data(), std::move(pass_val.data())); + static thread_local std::string name_val, pass_val; + string_view_to_string(name_val, name.value()); + string_view_to_string(pass_val, pass.value()); + bank.ChangePassword(name_val, std::move(pass_val)); } RESPOND_TRUE; } @@ -123,9 +123,9 @@ void api::SetBal(req_args) const } else { - static thread_local auto &name_val = name.value(); - *(char *)(name_val.data() + name_val.size()) = '\0'; //ignoring read-only - res = bank.SetBal(name_val.data(), amount.value()); + static thread_local std::string name_val; + string_view_to_string(name_val, name.value()); + res = bank.SetBal(name_val, amount.value()); } RESPONSE_PARSE(std::move(res)); } @@ -141,9 +141,9 @@ void api::ImpactBal(req_args) const } else { - static thread_local auto &name_val = name.value(); - *(char *)(name_val.data() + name_val.size()) = '\0'; //ignoring read-only - res = bank.ImpactBal(name_val.data(), amount.value()); + static thread_local std::string name_val; + string_view_to_string(name_val, name.value()); + res = bank.ImpactBal(name_val, amount.value()); } RESPONSE_PARSE(std::move(res)); } @@ -188,7 +188,6 @@ void api::ApiProperties(req_args) const CACHE_FOREVER; callback(resp); } - void api::AddUser(req_args) const { SIMD_JSON_GEN; @@ -201,10 +200,10 @@ void api::AddUser(req_args) const } else { - static thread_local auto &name_val = name.value(); - static thread_local auto &pass_val = pass.value(); - *(char *)(name_val.data() + name_val.size()) = *(char *)(pass_val.data() + pass_val.size()) = '\0'; //ignoring read-only - res = bank.AddUser(name_val.data(), 0, pass_val.data()); + static thread_local std::string name_val, pass_val; + string_view_to_string(name_val, name.value()); + string_view_to_string(pass_val, pass.value()); + res = bank.AddUser(std::move(name_val), 0, std::move(pass_val)); } RESPONSE_PARSE(std::move(res)); } @@ -221,10 +220,10 @@ void api::AdminAddUser(req_args) const } else { - static thread_local auto &name_val = name.value(); - static thread_local auto &pass_val = pass.value(); - *(char *)(name_val.data() + name_val.size()) = *(char *)(pass_val.data() + pass_val.size()) = '\0'; //ignoring read-only - res = bank.AddUser(name_val.data(), amount.value(), pass_val.data()); + static thread_local std::string name_val, pass_val; + string_view_to_string(name_val, name.value()); + string_view_to_string(pass_val, pass.value()); + res = bank.AddUser(std::move(name_val), amount.value(), std::move(pass_val)); } RESPONSE_PARSE(std::move(res)); } @@ -243,9 +242,9 @@ void api::AdminDelUser(req_args) const } else { - static thread_local auto &name_val = name.value(); - *(char *)(name_val.data() + name_val.size()) = '\0'; //ignoring read-only - res = bank.DelUser(name_val.data()); + static thread_local std::string name_val; + string_view_to_string(name_val, name.value()); + res = bank.DelUser(name_val); } RESPONSE_PARSE(std::move(res)); } diff --git a/src/str_intrusion.cpp b/src/str_intrusion.cpp new file mode 100644 index 0000000..70e47f9 --- /dev/null +++ b/src/str_intrusion.cpp @@ -0,0 +1,44 @@ +#include "str_intrusion.h" + +//this function is horribly jank +template +struct result +{ + typedef typename Tag::type type; + static type ptr; +}; +template +typename result::type result::ptr; + +template +struct rob : result +{ + struct filler + { + filler() { result::ptr = p; } + }; + static filler filler_obj; +}; +template +typename rob::filler rob::filler_obj; +struct string_length +{ + typedef void (std::string::*type)(size_t); +}; +template class rob; +struct string_data +{ + typedef void (std::string::*type)(char *); +}; +template class rob; +void string_view_to_string(std::string &str, std::string_view sv) +{ + (str.*result::ptr)((char *)sv.data()); + (str.*result::ptr)(sv.size()); +} +//may be used later +void destroy_string(std::string &str) +{ + (str.*result::ptr)(nullptr); + (str.*result::ptr)(0); +} \ No newline at end of file diff --git a/src/user_filter.cpp b/src/user_filter.cpp index b7849a4..498b948 100644 --- a/src/user_filter.cpp +++ b/src/user_filter.cpp @@ -9,12 +9,12 @@ void UserFilter::doFilter(const HttpRequestPtr &re FilterChainCallback &&fccb) { static thread_local std::string_view auth_header = req->getHeader("Authorization"); - if (auth_header.size() > 6) + if (auth_header.size() > 6 && auth_header.size() <= 517) //"Basic " + username + ':' + password { if (auth_header.substr(0, 6) == "Basic ") { static thread_local std::string_view base64_input = auth_header.substr(6); - static thread_local std::array base64_result; //255 username + ':' + 255 password + static thread_local std::array base64_result; //(255 username + ':' + 255 password) * 3/4 static thread_local size_t new_sz; base64_decode(base64_input.data(), base64_input.size(), base64_result.begin(), &new_sz, 0); @@ -22,14 +22,15 @@ void UserFilter::doFilter(const HttpRequestPtr &re static thread_local std::size_t middle = results_view.find(':'); if (middle != std::string::npos) { - base64_result[middle] = '\0'; - static thread_local const std::string &username(results_view.substr(0, middle).data()); + static thread_local std::string username; + string_view_to_string(username, results_view.substr(0, middle)); if constexpr (require_admin) { if (bank.AdminVerifyAccount(username)) { - base64_result[new_sz] = '\0'; - if (bank.VerifyPassword(username, results_view.substr(middle + 1))) + static thread_local std::string password; + string_view_to_string(password, results_view.substr(middle + 1)); + if (bank.VerifyPassword(username, password)) { fccb(); return; @@ -38,7 +39,8 @@ void UserFilter::doFilter(const HttpRequestPtr &re } else { - base64_result[new_sz] = '\0'; + static thread_local std::string password; + string_view_to_string(password, results_view.substr(middle + 1)); if (bank.VerifyPassword(username, results_view.substr(middle + 1))) { if constexpr (set_body_flag)