mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-14 08:48:31 +00:00
#102 Prevent Algo confusion attack
This commit is contained in:
parent
4a970bc302
commit
b9528b32eb
7 changed files with 82 additions and 2 deletions
|
@ -98,6 +98,8 @@ enum class VerificationErrc
|
|||
InvalidSignature,
|
||||
// Invalid value type used for known claims
|
||||
TypeConversionError,
|
||||
// Algorithm confusion attack detected
|
||||
AlgoConfusionAttack,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -186,3 +186,31 @@ TEST (DecodeTest, TypHeaderMiss)
|
|||
EXPECT_FALSE (ec);
|
||||
}
|
||||
|
||||
TEST (DecodeTest, AlgoConfusionAttack)
|
||||
{
|
||||
using namespace jwt::params;
|
||||
|
||||
using namespace jwt::params;
|
||||
|
||||
const char* enc_str =
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
|
||||
"eyJpYXQiOjE1MTM4NjIzNzEsImlkIjoiYS1iLWMtZC1lLWYtMS0yLTMiLCJpc3MiOiJhcnVuLm11cmFsaWRoYXJhbiIsInN1YiI6ImFkbWluIn0."
|
||||
"jk7bRQKTLvs1RcuvMc2B_rt6WBYPoVPirYi_QRBPiuk";
|
||||
|
||||
std::string pub_key = R"(-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh
|
||||
uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+
|
||||
iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM
|
||||
ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g
|
||||
6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe
|
||||
K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t
|
||||
BwIDAQAB
|
||||
-----END PUBLIC KEY-----)";
|
||||
|
||||
std::error_code ec;
|
||||
auto obj = jwt::decode(enc_str, algorithms({"HS256"}), ec, verify(true), secret(pub_key));
|
||||
|
||||
ASSERT_TRUE (ec);
|
||||
EXPECT_EQ (ec.value(), static_cast<int>(jwt::VerificationErrc::AlgoConfusionAttack));
|
||||
|
||||
}
|
|
@ -141,5 +141,4 @@ TEST (RSAAlgo, NoSpecificAlgo)
|
|||
|
||||
EXPECT_THROW (jwt::decode(enc_str, algorithms({"none", "HS384", "RS384"}), verify(true), secret(key)),
|
||||
jwt::InvalidAlgorithmError);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue