Generated WebSocket masks use a secure PRNG by default:

This resolves a medium vulnerability described in the
Beast Hybrid Assessment Report by Bishop Fox, where masks generated
for use with outgoing WebSocket client frames use an insufficient
source of entropy and a non-cryptographically secure pseudo-random
number generator.

By default, all newly constructed WebSocket streams will use a
uniquely seeded secure PRNG (ChaCha20 in counter mode). As this may
result in increased CPU resource consumption, the function
websocket::stream::secure_prng() may be used to select a faster but
less secure PRNG, for the case where the caller knows that the secure
generator is not necessary.

On some systems, std::random_device may produce insufficient entropy
to securely seed the PRNG. As this condition cannot be detected by
Beast, callers may use the function websocket::seed_prng() called
once at startup to provide at least 256 bits of entropy which will
be used to uniquely seed all subsequent PRNGs.
This commit is contained in:
Vinnie Falco committed 2018-07-08 15:20:05 -07:00
1 parent 68727b3cfb
commit 749e54f31b
16 files changed
+495 -139

No files matched your search

-1
View File
@@ -23,7 +23,6 @@ add_executable (tests-beast-websocket
error.cpp
frame.cpp
handshake.cpp
mask.cpp
option.cpp
ping.cpp
read1.cpp
-1
View File
@@ -13,7 +13,6 @@ local SOURCES =
error.cpp
frame.cpp
handshake.cpp
mask.cpp
option.cpp
ping.cpp
read1.cpp
-58
View File
@@ -1,58 +0,0 @@
//
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// Test that header file is self-contained.
#include <boost/beast/websocket/detail/mask.hpp>
#include <boost/beast/unit_test/suite.hpp>
namespace boost {
namespace beast {
namespace websocket {
namespace detail {
class mask_test : public beast::unit_test::suite
{
public:
struct test_generator
{
using result_type = std::uint32_t;
result_type n = 0;
void
seed(std::seed_seq const&)
{
}
void
seed(result_type const&)
{
}
std::uint32_t
operator()()
{
return n++;
}
};
void run() override
{
maskgen_t<test_generator> mg;
BEAST_EXPECT(mg() != 0);
}
};
BEAST_DEFINE_TESTSUITE(beast,websocket,mask);
} // detail
} // websocket
} // beast
} // boost
+8
View File
@@ -22,6 +22,11 @@ public:
void
testOptions()
{
{
std::seed_seq ss{42};
seed_prng(ss);
}
stream<test::stream> ws{ioc_};
ws.auto_fragment(true);
ws.write_buffer_size(2048);
@@ -37,6 +42,9 @@ public:
pass();
}
ws.secure_prng(true);
ws.secure_prng(false);
auto const bad =
[&](permessage_deflate const& pmd)
{