From ccc3f1e5a6536d9250d73608223e87b4f89669fd Mon Sep 17 00:00:00 2001 From: Johnathon Mohr Date: Tue, 15 Oct 2024 22:48:04 -0700 Subject: [PATCH 1/2] Ensure the mqtt address is an IPv4 (or at least not a domain) before determining it's private. --- src/mqtt/MQTT.cpp | 18 +++++++++++++----- src/mqtt/MQTT.h | 4 ++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 641583b625..5e5ebbec3d 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -704,26 +704,34 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json) (json.find("payload") != json.end()); // should have a payload } -bool MQTT::isPrivateIpAddress(const char ip[]) +bool MQTT::isPrivateIpAddress(const char address[]) { + // Ensure the address contains only digits and dots. + // Even if it's not a valid IP address, we will know it's not a domain. + for (int i = 0; i < strlen(address); i++) { + if (!isdigit(address[i]) && address[i] != '.') { + return false; + } + } + // Check the easy ones first. - if (strcmp(ip, "127.0.0.1") == 0 || strncmp(ip, "10.", 3) == 0 || strncmp(ip, "192.168", 7) == 0) { + if (strcmp(address, "127.0.0.1") == 0 || strncmp(address, "10.", 3) == 0 || strncmp(address, "192.168", 7) == 0) { return true; } // See if it's definitely not a 172 address. - if (strncmp(ip, "172", 3) != 0) { + if (strncmp(address, "172", 3) != 0) { return false; } // We know it's a 172 address, now see if the second octet is 2 digits. - if (ip[6] != '.') { + if (address[6] != '.') { return false; } // Copy the second octet into a secondary buffer we can null-terminate and parse. char octet2[3]; - strncpy(octet2, ip + 4, 2); + strncpy(octet2, address + 4, 2); octet2[2] = 0; int octet2Num = atoi(octet2); diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index fbfb7856ea..fcefb94a2c 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -120,9 +120,9 @@ class MQTT : private concurrency::OSThread // returns true if this is a valid JSON envelope which we accept on downlink bool isValidJsonEnvelope(JSONObject &json); - /// Determines if the given IP address is a private address, i.e. not routable on the public internet. + /// Determines if the given address is a private IPv4 address, i.e. not routable on the public internet. /// These are the ranges: 127.0.0.1, 10.0.0.0-10.255.255.255, 172.16.0.0-172.31.255.255, 192.168.0.0-192.168.255.255. - bool isPrivateIpAddress(const char ip[]); + bool isPrivateIpAddress(const char address[]); /// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server // int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; } From 18883dd09c02c208fa987db34f89f8aaba884a3b Mon Sep 17 00:00:00 2001 From: Johnathon Mohr Date: Wed, 16 Oct 2024 06:39:09 +0000 Subject: [PATCH 2/2] check address length --- src/mqtt/MQTT.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 5e5ebbec3d..45518153ef 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -706,9 +706,15 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json) bool MQTT::isPrivateIpAddress(const char address[]) { + // Min. length like 10.0.0.0, max like 192.168.255.255 + size_t length = strlen(address); + if (length < 8 || length > 15) { + return false; + } + // Ensure the address contains only digits and dots. // Even if it's not a valid IP address, we will know it's not a domain. - for (int i = 0; i < strlen(address); i++) { + for (int i = 0; i < length; i++) { if (!isdigit(address[i]) && address[i] != '.') { return false; }