High priority and critical issues

This commit is contained in:
2026-05-25 12:19:24 +02:00
parent 604e4ace0f
commit b64d9c4498
11 changed files with 213 additions and 80 deletions

View File

@@ -5,6 +5,7 @@
#include <asio.hpp>
#include <csignal>
#include <iostream>
#include <filesystem>
#include <columnlynx/common/utils.hpp>
#include <columnlynx/common/panic_handler.hpp>
#include <columnlynx/client/net/tcp/tcp_client.hpp>
@@ -90,7 +91,20 @@ int main(int argc, char** argv) {
std::string configPath = optionsObj["config-dir"].as<std::string>();
const char* envConfigPath = std::getenv("COLUMNLYNX_CONFIG_DIR");
if (envConfigPath != nullptr) {
configPath = std::string(envConfigPath);
// Validate and canonicalize environment-provided path
try {
namespace fs = std::filesystem;
std::error_code ec;
fs::path candidate(envConfigPath);
fs::path abs = fs::absolute(candidate, ec);
if (!ec) {
configPath = abs.string();
} else {
warn(std::string("Invalid COLUMNLYNX_CONFIG_DIR value: ") + envConfigPath + " - using default");
}
} catch (const std::exception& e) {
warn(std::string("Failed to canonicalize COLUMNLYNX_CONFIG_DIR: ") + e.what());
}
}
if (configPath.back() != '/' && configPath.back() != '\\') {

View File

@@ -159,7 +159,13 @@ namespace ColumnLynx::Net::TCP {
void TCPClient::mHandleMessage(ServerMessageType type, const std::string& data) {
switch (type) {
case ServerMessageType::HANDSHAKE_IDENTIFY: {
std::memcpy(mServerPublicKey, data.data(), std::min(data.size(), sizeof(mServerPublicKey)));
if (data.size() != sizeof(mServerPublicKey)) {
Utils::warn("HANDSHAKE_IDENTIFY has invalid size: " + std::to_string(data.size()));
disconnect();
return;
}
std::memcpy(mServerPublicKey, data.data(), sizeof(mServerPublicKey));
std::string hexServerPub = Utils::bytesToHexString(mServerPublicKey, 32);
Utils::log("Received server identity. Public Key: " + hexServerPub);
@@ -188,7 +194,13 @@ namespace ColumnLynx::Net::TCP {
{
// Verify the signature
Signature sig{};
std::memcpy(sig.data(), data.data(), std::min(data.size(), sig.size()));
if (data.size() != sig.size()) {
Utils::warn("HANDSHAKE_CHALLENGE_RESPONSE has invalid size: " + std::to_string(data.size()));
disconnect();
return;
}
std::memcpy(sig.data(), data.data(), sig.size());
if (Utils::LibSodiumWrapper::verifyMessage(mSubmittedChallenge.data(), mSubmittedChallenge.size(), sig, mServerPublicKey)) {
Utils::log("Challenge response verified successfully.");

View File

@@ -73,7 +73,7 @@ namespace ColumnLynx::Net::UDP {
reinterpret_cast<uint8_t*>(&hdr) + sizeof(UDPPacketHeader)
);
uint32_t sessionID = static_cast<uint32_t>(ClientSession::getInstance().getSessionID());
uint32_t sessionIDNet = sessionID;
uint32_t sessionIDNet = htonl(sessionID);
packet.insert(packet.end(),
reinterpret_cast<uint8_t*>(&sessionIDNet),
reinterpret_cast<uint8_t*>(&sessionIDNet) + sizeof(uint32_t)
@@ -136,9 +136,24 @@ namespace ColumnLynx::Net::UDP {
}
// Decrypt payload
// Extract ciphertext safely
size_t headerLen = sizeof(UDPPacketHeader) + sizeof(uint32_t);
if (bytes < headerLen) {
Utils::warn("UDP Client received packet too small after header check.");
return;
}
size_t ciphertextLen = bytes - headerLen;
// Enforce reasonable maximum (UDP payload practical limit)
const size_t MAX_UDP_PAYLOAD = 65507; // 65535 - UDP/IP headers
if (ciphertextLen > MAX_UDP_PAYLOAD) {
Utils::warn("UDP Client received packet with excessive payload size: " + std::to_string(ciphertextLen));
return;
}
std::vector<uint8_t> ciphertext(
mRecvBuffer.begin() + sizeof(UDPPacketHeader) + sizeof(uint32_t),
mRecvBuffer.begin() + bytes
mRecvBuffer.begin() + headerLen,
mRecvBuffer.begin() + headerLen + ciphertextLen
);
if (ClientSession::getInstance().getAESKey().empty()) {