CVE-2022-3959 (C, published 2022-11-11T16:15Z)
Description: value: A vulnerability, which was classified as problematic, has been found in drogon up to 1.8.1. Affected by this issue is some unknown functionality of the component Session Hash Handler. The manipulation leads to small space of random values. The attack may be launched remotely. Upgrading to version 1.8.2 is able to address this issue. The name of the patch is c0d48da99f66aaada17bcd28b07741cac8697647. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-213464.
Severity: nan (CVSS v3 base score: 5.3)
Weakness: CWE-330 \u2014 Use of Insufficiently Random Values
The product uses insufficiently random numbers or values in a security context that depends on unpredictable numbers.
Repository: https://github.com/drogonframework/drogon
Files changed:
lib/inc/drogon/HttpRequest.h
lib/inc/drogon/HttpResponse.h
lib/inc/drogon/utils/Utilities.h
lib/src/HttpRequestImpl.h
lib/src/HttpResponseImpl.h
lib/src/Utilities.cc
Commit message: Avoid HashDoS attacks via random per-session hash initial state (#1433)



Vulnerable code:
    virtual const std::unordered_map<std::string, std::string> &headers()
        const = 0;
    const std::unordered_map<std::string, std::string> &getHeaders() const
    virtual const std::unordered_map<std::string, std::string> &cookies()
        const = 0;
    const std::unordered_map<std::string, std::string> &getCookies() const
    virtual const std::unordered_map<std::string, std::string> &parameters()
        const = 0;
    const std::unordered_map<std::string, std::string> &getParameters() const
    virtual const std::unordered_map<std::string, std::string> &headers()
        const = 0;
    const std::unordered_map<std::string, std::string> &getHeaders() const
    virtual const std::unordered_map<std::string, Cookie> &cookies() const = 0;
    const std::unordered_map<std::string, Cookie> &getCookies() const
    const std::unordered_map<std::string, std::string> &parameters()
        const override
    const std::unordered_map<std::string, std::string> &headers() const override
    const std::unordered_map<std::string, std::string> &cookies() const override
    std::unordered_map<std::string, std::string> headers_;
    std::unordered_map<std::string, std::string> cookies_;
    mutable std::unordered_map<std::string, std::string> parameters_;
    const std::unordered_map<std::string, std::string> &headers() const override
    const std::unordered_map<std::string, Cookie> &cookies() const override
    std::unordered_map<std::string, std::string> headers_;
    std::unordered_map<std::string, Cookie> cookies_;

Fixed code:
    virtual const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &headers() const = 0;
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &getHeaders() const
    virtual const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &cookies() const = 0;
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &getCookies() const
    virtual const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &parameters() const = 0;
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &getParameters() const
#include <drogon/utils/Utilities.h>
    virtual const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &headers() const = 0;
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &getHeaders() const
    virtual const std::
        unordered_map<std::string, Cookie, utils::internal::SafeStringHash>
            &cookies() const = 0;
    const std::
        unordered_map<std::string, Cookie, utils::internal::SafeStringHash>
            &getCookies() const

namespace internal
{
DROGON_EXPORT extern const size_t fixedRandomNumber;
struct SafeStringHash
{
    size_t operator()(const std::string &str) const
    {
        const size_t A = 6665339;
        const size_t B = 2534641;
        size_t h = fixedRandomNumber;
        for (char ch : str)
            h = (h * A) ^ (ch * B);
        return h;
    }
};
}  // namespace internal
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &parameters() const override
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &headers() const override
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &cookies() const override
    std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            headers_;
    std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            cookies_;
    mutable std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            parameters_;
    const std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            &headers() const override
    const std::
        unordered_map<std::string, Cookie, utils::internal::SafeStringHash>
            &cookies() const override
    std::
        unordered_map<std::string, std::string, utils::internal::SafeStringHash>
            headers_;
    std::unordered_map<std::string, Cookie, utils::internal::SafeStringHash>
        cookies_;
namespace internal
{
DROGON_EXPORT const size_t fixedRandomNumber = []() {
    size_t res;
    utils::secureRandomBytes(&res, sizeof(res));
    return res;
}();
}