diff --git a/src/tawashi/error_reasons.hpp b/src/tawashi/error_reasons.hpp index 2d3986f..78b6fc9 100644 --- a/src/tawashi/error_reasons.hpp +++ b/src/tawashi/error_reasons.hpp @@ -29,6 +29,7 @@ namespace tawashi { MissingPostVariable, PastieNotFound, InvalidContentType, - UnsupportedContentType + UnsupportedContentType, + InvalidToken ) } //namespace tawashi diff --git a/src/tawashi/error_response.cpp b/src/tawashi/error_response.cpp index 0a1fe70..97ba848 100644 --- a/src/tawashi/error_response.cpp +++ b/src/tawashi/error_response.cpp @@ -52,7 +52,8 @@ namespace tawashi { "Request is missing a POST variable.", "Pastie not found.", "Invalid CONTENT_TYPE.", - "Unsupported CONTENT_TYPE." + "Unsupported CONTENT_TYPE.", + "Invalid pastie token." }; constexpr const auto lengths = string_lengths(err_descs); static_assert(err_descs.static_size == lengths.static_size, "Mismatching array sizes between strings and their lengths"); diff --git a/src/tawashi/pastie_response.cpp b/src/tawashi/pastie_response.cpp index 85d95c8..22637ef 100644 --- a/src/tawashi/pastie_response.cpp +++ b/src/tawashi/pastie_response.cpp @@ -20,6 +20,7 @@ #include "settings_bag.hpp" #include "escapist.hpp" #include "cgi_env.hpp" +#include "spdlog.hpp" #include #include #include @@ -68,6 +69,25 @@ namespace tawashi { }) ); } + + bool is_valid_token (const boost::string_view& parToken) { + if (parToken.empty()) + return false; + auto it_mark = std::find(parToken.begin(), parToken.end(), '?'); + if (parToken.begin() == it_mark) + return false; + for (auto it_ch = parToken.begin(); it_ch != it_mark; ++it_ch) { + if (*it_ch < 'a' or *it_ch > 'z') { + spdlog::get("statuslog")->info( + "Token's byte {} is invalid; value={}", + it_ch - parToken.begin(), + static_cast(*it_ch) + ); + return false; + } + } + return true; + } } //unnamed namespace PastieResponse::PastieResponse ( @@ -79,14 +99,16 @@ namespace tawashi { m_langmap_dir(parSettings->as("langmap_dir")), m_plain_text(false), m_syntax_highlight(true), - m_pastie_not_found(false) + m_pastie_not_found(false), + m_token_invalid(false) { } HttpHeader PastieResponse::on_process() { - if (m_pastie_not_found) { + if (m_pastie_not_found) return make_error_redirect(ErrorReasons::PastieNotFound); - } + if (m_token_invalid) + return make_error_redirect(ErrorReasons::InvalidToken); auto get = cgi_env().query_string_split(); const std::string& query_str(cgi_env().query_string()); @@ -113,6 +135,10 @@ namespace tawashi { boost::string_view token = get_pastie_name(cgi_env().request_uri_relative()); boost::optional pastie = this->storage().retrieve_pastie(token); + if (not is_valid_token(token)) { + m_token_invalid = true; + return; + } if (not pastie) { m_pastie_not_found = true; return; diff --git a/src/tawashi/pastie_response.hpp b/src/tawashi/pastie_response.hpp index 86e5f65..6d0044e 100644 --- a/src/tawashi/pastie_response.hpp +++ b/src/tawashi/pastie_response.hpp @@ -43,5 +43,6 @@ namespace tawashi { bool m_plain_text; bool m_syntax_highlight; bool m_pastie_not_found; + bool m_token_invalid; }; } //namespace tawashi