Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1952)

Unified Diff: webrtc/p2p/base/turnport_unittest.cc

Issue 2440043004: Preventing TURN redirects to loopback addresses. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/p2p/base/turnport.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/p2p/base/turnport_unittest.cc
diff --git a/webrtc/p2p/base/turnport_unittest.cc b/webrtc/p2p/base/turnport_unittest.cc
index edb345447bf592187f7da4857ff823cd7ec9039d..a8153eed268a8ec851bb0a213b7453fc4f251f4e 100644
--- a/webrtc/p2p/base/turnport_unittest.cc
+++ b/webrtc/p2p/base/turnport_unittest.cc
@@ -29,6 +29,7 @@
#include "webrtc/base/helpers.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/physicalsocketserver.h"
+#include "webrtc/base/socketadapters.h"
#include "webrtc/base/socketaddress.h"
#include "webrtc/base/ssladapter.h"
#include "webrtc/base/thread.h"
@@ -441,6 +442,57 @@ class TurnPortTest : public testing::Test,
ASSERT_EQ(0U, turn_port_->Candidates().size());
}
+ // A certain security exploit works by redirecting to a loopback address,
+ // which doesn't ever actually make sense. So redirects to loopback should
+ // be treated as errors.
+ // See: https://bugs.chromium.org/p/chromium/issues/detail?id=649118
+ void TestTurnAlternateServerLoopback(ProtocolType protocol_type, bool ipv6) {
+ const SocketAddress& local_address = ipv6 ? kLocalIPv6Addr : kLocalAddr1;
+ const SocketAddress& server_address =
+ ipv6 ? kTurnIPv6IntAddr : kTurnIntAddr;
+
+ std::vector<rtc::SocketAddress> redirect_addresses;
+ SocketAddress loopback_address(ipv6 ? "::1" : "127.0.0.1",
+ TURN_SERVER_PORT);
+ redirect_addresses.push_back(loopback_address);
+
+ // Make a socket and bind it to the local port, to make extra sure no
+ // packet is sent to this address.
+ std::unique_ptr<rtc::Socket> loopback_socket(ss_->CreateSocket(
+ protocol_type == PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM));
+ ASSERT_NE(nullptr, loopback_socket.get());
+ ASSERT_EQ(0, loopback_socket->Bind(loopback_address));
+ if (protocol_type == PROTO_TCP) {
+ ASSERT_EQ(0, loopback_socket->Listen(1));
+ }
+
+ TestTurnRedirector redirector(redirect_addresses);
+
+ turn_server_.AddInternalSocket(server_address, protocol_type);
+ turn_server_.set_redirect_hook(&redirector);
+ CreateTurnPort(local_address, kTurnUsername, kTurnPassword,
+ ProtocolAddress(server_address, protocol_type));
+
+ turn_port_->PrepareAddress();
+ EXPECT_TRUE_SIMULATED_WAIT(
+ turn_error_,
+ (protocol_type == PROTO_TCP ? kSimulatedRtt * 3 : kSimulatedRtt * 2),
+ fake_clock_);
+
+ // Wait for some extra time, and make sure no packets were received on the
+ // loopback port we created (or in the case of TCP, no connection attempt
+ // occurred).
+ SIMULATED_WAIT(false, kSimulatedRtt, fake_clock_);
+ if (protocol_type == PROTO_UDP) {
+ char buf[1];
+ EXPECT_EQ(-1, loopback_socket->Recv(&buf, 1, nullptr));
+ } else {
+ std::unique_ptr<rtc::Socket> accepted_socket(
+ loopback_socket->Accept(nullptr));
+ EXPECT_EQ(nullptr, accepted_socket.get());
+ }
+ }
+
void TestTurnConnection(ProtocolType protocol_type) {
// Create ports and prepare addresses.
PrepareTurnAndUdpPorts(protocol_type);
@@ -917,6 +969,23 @@ TEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetitionTCP) {
TestTurnAlternateServerDetectRepetition(PROTO_TCP);
}
+// Test catching the case of a redirect to loopback.
+TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv4) {
+ TestTurnAlternateServerLoopback(PROTO_UDP, false);
+}
+
+TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackUdpIpv6) {
+ TestTurnAlternateServerLoopback(PROTO_UDP, true);
+}
+
+TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv4) {
+ TestTurnAlternateServerLoopback(PROTO_TCP, false);
+}
+
+TEST_F(TurnPortTest, TestTurnAlternateServerLoopbackTcpIpv6) {
+ TestTurnAlternateServerLoopback(PROTO_TCP, true);
+}
+
// Do a TURN allocation and try to send a packet to it from the outside.
// The packet should be dropped. Then, try to send a packet from TURN to the
// outside. It should reach its destination. Finally, try again from the
« no previous file with comments | « webrtc/p2p/base/turnport.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698