mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 01:23:24 -08:00
[Servatrice] Match trusted_sources by address, not substring (#7582)
trusted_sources was checked with QString::contains. A dual-stack listener reports a local proxy as ::ffff:127.0.0.1, which never matches the default "127.0.0.1,::1". Behind nginx the forwarded client IP header was then ignored, every websocket user shared the proxy's address, and logins failed with "too many concurrent connections" once max_users_per_address was reached. Add isTrustedSource(), which parses each entry as a QHostAddress and compares exact addresses with IPv4-mapped addresses normalized, and use it at all four call sites. The ban command also read server/trusted_sources instead of the documented security/trusted_sources; it now uses the same getter. Entries that are not IP addresses are logged at startup since they no longer match anything. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4343544588
commit
46cdbac830
9 changed files with 136 additions and 9 deletions
58
tests/trusted_sources_test.cpp
Normal file
58
tests/trusted_sources_test.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include "trusted_sources.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <QHostAddress>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const QString kDefault = QStringLiteral("127.0.0.1,::1");
|
||||
|
||||
TEST(TrustedSourcesTest, MatchesListedAddresses)
|
||||
{
|
||||
ASSERT_TRUE(isTrustedSource(kDefault, QHostAddress("127.0.0.1")));
|
||||
ASSERT_TRUE(isTrustedSource(kDefault, QHostAddress("::1")));
|
||||
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress("10.0.0.1")));
|
||||
}
|
||||
|
||||
TEST(TrustedSourcesTest, MatchesIpv4MappedPeerAgainstPlainIpv4Entry)
|
||||
{
|
||||
// A dual-stack listener reports a local IPv4 proxy as ::ffff:127.0.0.1;
|
||||
// it must still match the default 127.0.0.1 entry.
|
||||
ASSERT_TRUE(isTrustedSource(kDefault, QHostAddress("::ffff:127.0.0.1")));
|
||||
}
|
||||
|
||||
TEST(TrustedSourcesTest, MatchesPlainIpv4PeerAgainstMappedEntry)
|
||||
{
|
||||
ASSERT_TRUE(isTrustedSource("::ffff:192.0.2.7", QHostAddress("192.0.2.7")));
|
||||
}
|
||||
|
||||
TEST(TrustedSourcesTest, DoesNotMatchSubstrings)
|
||||
{
|
||||
// Substring matching would let 27.0.0.1 or 0.0.1 pass as 127.0.0.1.
|
||||
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress("27.0.0.1")));
|
||||
ASSERT_FALSE(isTrustedSource("192.0.2.10", QHostAddress("192.0.2.1")));
|
||||
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress(":")));
|
||||
}
|
||||
|
||||
TEST(TrustedSourcesTest, ToleratesWhitespaceAndCase)
|
||||
{
|
||||
ASSERT_TRUE(isTrustedSource(" 192.0.2.7 , 2001:DB8::1 ", QHostAddress("2001:db8::1")));
|
||||
ASSERT_TRUE(isTrustedSource(" 192.0.2.7 , 2001:DB8::1 ", QHostAddress("192.0.2.7")));
|
||||
}
|
||||
|
||||
TEST(TrustedSourcesTest, IgnoresMalformedEntriesAndNullAddresses)
|
||||
{
|
||||
ASSERT_FALSE(isTrustedSource("not-an-ip,,", QHostAddress("127.0.0.1")));
|
||||
ASSERT_FALSE(isTrustedSource("", QHostAddress("127.0.0.1")));
|
||||
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress()));
|
||||
}
|
||||
|
||||
TEST(TrustedSourcesTest, StringOverloadParsesAddress)
|
||||
{
|
||||
ASSERT_TRUE(isTrustedSource(kDefault, QStringLiteral("::ffff:127.0.0.1")));
|
||||
ASSERT_FALSE(isTrustedSource(kDefault, QStringLiteral("27.0.0.1")));
|
||||
ASSERT_FALSE(isTrustedSource(kDefault, QString()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Loading…
Add table
Add a link
Reference in a new issue