Skip to content

Commit 754c9bf

Browse files
tniessendanielleadams
authored andcommitted
src: fix IPv4 validation in inspector_socket
Co-authored-by: RafaelGSS <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: RafaelGSS <[email protected]> PR-URL: nodejs-private/node-private#320 CVE-ID: CVE-2022-32212 Backport-PR-URL: nodejs-private/node-private#323
1 parent c6553a4 commit 754c9bf

File tree

2 files changed

+87
-5
lines changed

2 files changed

+87
-5
lines changed

src/inspector_socket.cc

+13-5
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,22 @@ static std::string TrimPort(const std::string& host) {
164164
static bool IsIPAddress(const std::string& host) {
165165
if (host.length() >= 4 && host.front() == '[' && host.back() == ']')
166166
return true;
167-
int quads = 0;
167+
uint_fast16_t accum = 0;
168+
uint_fast8_t quads = 0;
169+
bool empty = true;
170+
auto endOctet = [&accum, &quads, &empty](bool final = false) {
171+
return !empty && accum <= 0xff && ++quads <= 4 && final == (quads == 4) &&
172+
(empty = true) && !(accum = 0);
173+
};
168174
for (char c : host) {
169-
if (c == '.')
170-
quads++;
171-
else if (!isdigit(c))
175+
if (isdigit(c)) {
176+
if ((accum = (accum * 10) + (c - '0')) > 0xff) return false;
177+
empty = false;
178+
} else if (c != '.' || !endOctet()) {
172179
return false;
180+
}
173181
}
174-
return quads == 3;
182+
return endOctet(true);
175183
}
176184

177185
// Constants for hybi-10 frame format.

test/cctest/test_inspector_socket.cc

+74
Original file line numberDiff line numberDiff line change
@@ -851,4 +851,78 @@ TEST_F(InspectorSocketTest, HostCheckedForUPGRADE) {
851851
expect_failure_no_delegate(UPGRADE_REQUEST);
852852
}
853853

854+
TEST_F(InspectorSocketTest, HostIPChecked) {
855+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
856+
"Host: 10.0.2.555:9229\r\n\r\n";
857+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
858+
INVALID_HOST_IP_REQUEST.length());
859+
expect_handshake_failure();
860+
}
861+
862+
TEST_F(InspectorSocketTest, HostNegativeIPChecked) {
863+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
864+
"Host: 10.0.-23.255:9229\r\n\r\n";
865+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
866+
INVALID_HOST_IP_REQUEST.length());
867+
expect_handshake_failure();
868+
}
869+
870+
TEST_F(InspectorSocketTest, HostIpOctetOutOfIntRangeChecked) {
871+
const std::string INVALID_HOST_IP_REQUEST =
872+
"GET /json HTTP/1.1\r\n"
873+
"Host: 127.0.0.4294967296:9229\r\n\r\n";
874+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
875+
INVALID_HOST_IP_REQUEST.length());
876+
expect_handshake_failure();
877+
}
878+
879+
TEST_F(InspectorSocketTest, HostIpOctetFarOutOfIntRangeChecked) {
880+
const std::string INVALID_HOST_IP_REQUEST =
881+
"GET /json HTTP/1.1\r\n"
882+
"Host: 127.0.0.18446744073709552000:9229\r\n\r\n";
883+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
884+
INVALID_HOST_IP_REQUEST.length());
885+
expect_handshake_failure();
886+
}
887+
888+
TEST_F(InspectorSocketTest, HostIpEmptyOctetStartChecked) {
889+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
890+
"Host: .0.0.1:9229\r\n\r\n";
891+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
892+
INVALID_HOST_IP_REQUEST.length());
893+
expect_handshake_failure();
894+
}
895+
896+
TEST_F(InspectorSocketTest, HostIpEmptyOctetMidChecked) {
897+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
898+
"Host: 127..0.1:9229\r\n\r\n";
899+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
900+
INVALID_HOST_IP_REQUEST.length());
901+
expect_handshake_failure();
902+
}
903+
904+
TEST_F(InspectorSocketTest, HostIpEmptyOctetEndChecked) {
905+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
906+
"Host: 127.0.0.:9229\r\n\r\n";
907+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
908+
INVALID_HOST_IP_REQUEST.length());
909+
expect_handshake_failure();
910+
}
911+
912+
TEST_F(InspectorSocketTest, HostIpTooFewOctetsChecked) {
913+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
914+
"Host: 127.0.1:9229\r\n\r\n";
915+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
916+
INVALID_HOST_IP_REQUEST.length());
917+
expect_handshake_failure();
918+
}
919+
920+
TEST_F(InspectorSocketTest, HostIpTooManyOctetsChecked) {
921+
const std::string INVALID_HOST_IP_REQUEST = "GET /json HTTP/1.1\r\n"
922+
"Host: 127.0.0.0.1:9229\r\n\r\n";
923+
send_in_chunks(INVALID_HOST_IP_REQUEST.c_str(),
924+
INVALID_HOST_IP_REQUEST.length());
925+
expect_handshake_failure();
926+
}
927+
854928
} // anonymous namespace

0 commit comments

Comments
 (0)