#102 Prevent Algo confusion attack

This commit is contained in:
arunmu-nx 2025-04-22 18:49:16 +05:30
parent 4a970bc302
commit b9528b32eb
7 changed files with 82 additions and 2 deletions

View file

@ -98,6 +98,8 @@ enum class VerificationErrc
InvalidSignature,
// Invalid value type used for known claims
TypeConversionError,
// Algorithm confusion attack detected
AlgoConfusionAttack,
};
/**

View file

@ -25,6 +25,31 @@ SOFTWARE.
namespace jwt {
verify_result_t is_secret_a_public_key(const jwt::string_view secret)
{
std::error_code ec{};
BIO_uptr bufkey{
BIO_new_mem_buf((void*)secret.data(), static_cast<int>(secret.length())),
bio_deletor
};
if (!bufkey) {
throw MemoryAllocationException("BIO_new_mem_buf failed");
}
EC_PKEY_uptr pkey{
PEM_read_bio_PUBKEY(bufkey.get(), nullptr, nullptr, nullptr),
ev_pkey_deletor
};
if (!pkey) {
ec = AlgorithmErrc::InvalidKeyErr;
return { false, ec };
}
return {true, ec};
}
template <typename Hasher>
verify_result_t HMACSign<Hasher>::verify(
const jwt::string_view key,

View file

@ -124,6 +124,8 @@ struct VerificationErrorCategory: std::error_category
return "invalid signature";
case VerificationErrc::TypeConversionError:
return "type conversion error";
case VerificationErrc::AlgoConfusionAttack:
return "algo confusion attack possibility";
};
return "unknown verification error";
}

View file

@ -195,10 +195,30 @@ inline verify_result_t jwt_signature::verify(const jwt_header& header,
const jwt::string_view hdr_pld_sign,
const jwt::string_view jwt_sign)
{
auto check_res = check_for_algo_confusion_attack(header);
if (check_res.first) {
return {false, VerificationErrc::AlgoConfusionAttack};
}
verify_func_t verify_fn = get_verify_algorithm_impl(header);
return verify_fn(key_, hdr_pld_sign, jwt_sign);
}
inline verify_result_t jwt_signature::check_for_algo_confusion_attack(
const jwt_header& hdr) const
{
switch (hdr.algo()) {
case algorithm::RS256:
case algorithm::RS384:
case algorithm::RS512:
return {false, std::error_code{}};
default:
// For all other cases make sure that the secret provided
// is not the public key.
return is_secret_a_public_key(key_);
}
}
inline sign_func_t
jwt_signature::get_sign_algorithm_impl(const jwt_header& hdr) const noexcept

View file

@ -829,6 +829,10 @@ private: // Private implementation
*/
verify_func_t get_verify_algorithm_impl(const jwt_header& hdr) const noexcept;
/*!
*/
verify_result_t check_for_algo_confusion_attack(const jwt_header& hdr) const;
private: // Data members;
/// The key for creating the JWS