Merge pull request #2557 from jpk68/add-checks

fix: missing checks and limits
This commit is contained in:
orignal authored and GitHub committed 2026-09-16 09:00:11 -04:00
commit 87340e65db
9 files changed
+46 -8

No files matched your search

+16 -2
View File
@@ -709,7 +709,9 @@ namespace http {
if (i2cpServer)
{
s << "<b>I2CP " << tr("Local Destination") << ":</b><br>\r\n<br>\r\n";
auto session = i2cpServer->FindSessionByID ((uint16_t)std::stoi (id));
std::shared_ptr<i2p::client::I2CPSession> session;
try { session = i2cpServer->FindSessionByID ((uint16_t)std::stoi (id)); }
catch (std::exception&) {}
if (session)
ShowLeaseSetDestination (s, session->GetDestination (), 0);
else
@@ -1505,7 +1507,19 @@ namespace http {
std::string redirect = std::to_string(COMMAND_REDIRECT_TIMEOUT) + "; url=" + webroot + "?page=commands";
std::string token = params["token"];
if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ())
if (token.empty ())
{
ShowError(s, tr("Invalid token"));
return;
}
int tokenValue;
try { tokenValue = std::stoi (token); }
catch (std::exception&)
{
ShowError(s, tr("Invalid token"));
return;
}
if (m_Tokens.find (tokenValue) == m_Tokens.end ())
{
ShowError(s, tr("Invalid token"));
return;
+5
View File
@@ -260,6 +260,11 @@ namespace client
LogPrint (eLogError, "I2PControl: Malformed request, HTTP header expected");
return; // TODO:
}
if (contentLength > I2P_CONTROL_MAX_CONTENT_LENGTH)
{
LogPrint (eLogError, "I2PControl: Content-Length ", contentLength, " exceeds maximum allowed size");
return;
}
std::streamoff rem = contentLength + ss.tellg () - bytes_transferred; // more bytes to read
while (rem > 0) // read in chunks to prevent buffer overflow
{
+1
View File
@@ -28,6 +28,7 @@ namespace client
{
const size_t I2P_CONTROL_MAX_REQUEST_SIZE = 1024;
typedef std::array<char, I2P_CONTROL_MAX_REQUEST_SIZE> I2PControlBuffer;
const size_t I2P_CONTROL_MAX_CONTENT_LENGTH = 65536; // sanity limit on declared HTTP Content-Length
const uint64_t I2P_CONTROL_TOKEN_LIFETIME = 60*60; // 1 hour, in seconds
const long I2P_CONTROL_CERTIFICATE_VALIDITY = 365*10; // 10 years
+1
View File
@@ -556,6 +556,7 @@ namespace data
if (allzeros)
{
// offline information
if (ret + 6 > len) return 0; // expires(4) + key type(2)
const uint8_t * offlineInfo = buf + ret;
uint32_t expires = bufbe32toh (buf + ret); ret += 4; // expires timestamp
if (expires < i2p::util::GetSecondsSinceEpoch ())
+1
View File
@@ -1419,6 +1419,7 @@ namespace data
void NetDb::ManageLeaseSets ()
{
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
std::lock_guard<std::mutex> lock(m_LeaseSetsMutex);
for (auto it = m_LeaseSets.begin (); it != m_LeaseSets.end ();)
{
if (!it->second->IsValid () || ts > it->second->GetExpirationTime () - LEASE_ENDDATE_THRESHOLD)
+3 -3
View File
@@ -270,7 +270,7 @@ namespace data
if (it != m_SigningKeys.end ())
{
// TODO: implement all signature types
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096)
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096 && signatureLength >= SHA512_DIGEST_LENGTH)
{
size_t pos = s.tellg ();
size_t tbsLen = pos + contentLength;
@@ -282,7 +282,7 @@ namespace data
// RSA-raw
{
// calculate digest
uint8_t digest[64];
uint8_t digest[SHA512_DIGEST_LENGTH];
SHA512 (tbs, tbsLen, digest);
// encrypt signature
BN_CTX * bnctx = BN_CTX_new ();
@@ -294,7 +294,7 @@ namespace data
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
// digest is right aligned
// we can't use RSA_verify due wrong padding in SU3
if (memcmp (enSigBuf + (signatureLength - 64), digest, 64))
if (memcmp (enSigBuf + (signatureLength - SHA512_DIGEST_LENGTH), digest, SHA512_DIGEST_LENGTH))
LogPrint (eLogWarning, "Reseed: SU3 signature verification failed");
else
verify = false; // verified
+3 -2
View File
@@ -644,11 +644,12 @@ namespace data
std::string_view RouterInfo::ExtractString (const uint8_t * buf, size_t len) const
{
if (!len) return {};
uint8_t l = buf[0];
if (l > len)
if (l > len - 1)
{
LogPrint (eLogWarning, "RouterInfo: String length ", (int)l, " exceeds buffer size ", len);
l = len;
l = len - 1;
}
return { (const char *)(buf + 1), l };
}
+1 -1
View File
@@ -272,7 +272,7 @@ namespace util
{
if (!len) return { };
uint8_t l = buf[0];
if (l > len) l = len;
if (l > len - 1) l = len - 1;
return { (const char *)(buf + 1), l };
}
+15
View File
@@ -882,6 +882,11 @@ namespace client
void I2CPSession::CreateLeaseSet2MessageHandler (const uint8_t * buf, size_t len)
{
if (len < 3)
{
LogPrint (eLogError, "I2CP: CreateLeaseSet2Message is too short ", len);
return;
}
uint16_t sessionID = bufbe16toh (buf);
if (sessionID == m_SessionID)
{
@@ -897,6 +902,11 @@ namespace client
}
offset += ls.GetBufferLen ();
// private keys
if (offset >= len)
{
LogPrint (eLogError, "I2CP: CreateLeaseSet2Message is too short for private keys");
return;
}
int numPrivateKeys = buf[offset]; offset++;
for (int i = 0; i < numPrivateKeys; i++)
{
@@ -1074,6 +1084,11 @@ namespace client
void I2CPSession::DestLookupMessageHandler (const uint8_t * buf, size_t len)
{
if (len < 32)
{
LogPrint (eLogError, "I2CP: DestLookupMessage is too short ", len);
return;
}
if (m_Destination)
{
auto ls = m_Destination->FindLeaseSet (buf);