From b74957d9d4b8fbec07d9aa9f40e56a979e4133e1 Mon Sep 17 00:00:00 2001 From: Daniel-Eisenberg <59121493+Daniel-Eisenberg@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:19:15 +0300 Subject: [PATCH] Fix alpine ca (#354) * fix ca loading for alpine * fix ca loading for alpine * fix ca loading for alpine * change gzipped detection * change gzipped detection --------- Co-authored-by: Daniel Eisenberg --- build_system/docker/Dockerfile | 2 + .../waap/waap_clib/CMakeLists.txt | 1 + .../waap/waap_clib/DeepParser.cc | 5 + .../waap/waap_clib/ParserGzip.cc | 115 ++++++++++++++++++ .../security_apps/waap/waap_clib/ParserGzip.h | 46 +++++++ .../waap/waap_clib/Serializator.cc | 12 +- .../waap/waap_clib/WaapValueStatsAnalyzer.cc | 2 +- .../security_apps/waap/waap_clib/Waf2Util.cc | 11 ++ .../security_apps/waap/waap_clib/Waf2Util.h | 1 + .../services_sdk/resources/debug_flags.h | 1 + core/messaging/connection/connection.cc | 32 ++++- 11 files changed, 213 insertions(+), 15 deletions(-) create mode 100755 components/security_apps/waap/waap_clib/ParserGzip.cc create mode 100755 components/security_apps/waap/waap_clib/ParserGzip.h diff --git a/build_system/docker/Dockerfile b/build_system/docker/Dockerfile index 70eba5f..3489bb0 100644 --- a/build_system/docker/Dockerfile +++ b/build_system/docker/Dockerfile @@ -13,8 +13,10 @@ RUN apk add --no-cache libunwind RUN apk add --no-cache gdb RUN apk add --no-cache libxml2 RUN apk add --no-cache pcre2 +RUN apk add --no-cache ca-certificates RUN apk add --update coreutils + COPY self_managed_openappsec_manifest.json /tmp/self_managed_openappsec_manifest.json COPY install*.sh /nano-service-installers/ diff --git a/components/security_apps/waap/waap_clib/CMakeLists.txt b/components/security_apps/waap/waap_clib/CMakeLists.txt index 67277c5..55309a7 100755 --- a/components/security_apps/waap/waap_clib/CMakeLists.txt +++ b/components/security_apps/waap/waap_clib/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(waap_clib ParserJson.cc ParserMultipartForm.cc ParserRaw.cc + ParserGzip.cc ParserUrlEncode.cc ParserXML.cc ParserDelimiter.cc diff --git a/components/security_apps/waap/waap_clib/DeepParser.cc b/components/security_apps/waap/waap_clib/DeepParser.cc index 06d2c54..af97ab8 100755 --- a/components/security_apps/waap/waap_clib/DeepParser.cc +++ b/components/security_apps/waap/waap_clib/DeepParser.cc @@ -22,6 +22,7 @@ #include "ParserXML.h" #include "ParserHTML.h" #include "ParserBinary.h" +#include "ParserGzip.h" #include "ParserMultipartForm.h" #include "ParserPercentEncode.h" #include "ParserPairs.h" @@ -1261,6 +1262,10 @@ DeepParser::createInternalParser( dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse an HTML file"; m_parsersDeque.push_back(std::make_shared>(*this, parser_depth + 1)); offset = 0; + } else if (isBodyPayload && Waap::Util::isGzipped(cur_val)){ + dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse a gzip file"; + m_parsersDeque.push_back(std::make_shared>(*this, parser_depth + 1)); + offset = 0; } else if (cur_val.size() > 0 && signatures->php_serialize_identifier.hasMatch(cur_val)) { // PHP value detected dbgTrace(D_WAAP_DEEP_PARSER) << "Starting to parse phpSerializedData"; diff --git a/components/security_apps/waap/waap_clib/ParserGzip.cc b/components/security_apps/waap/waap_clib/ParserGzip.cc new file mode 100755 index 0000000..893ba8e --- /dev/null +++ b/components/security_apps/waap/waap_clib/ParserGzip.cc @@ -0,0 +1,115 @@ +// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ParserGzip.h" +#include "debug.h" + +USE_DEBUG_FLAG(D_WAAP_PARSER_GZIP); + +const std::string ParserGzip::m_parserName = "ParserGzip"; + +ParserGzip::ParserGzip(IParserStreamReceiver &receiver, size_t parser_depth) +:m_receiver(receiver), m_key("gzip"), m_state(s_start), m_stream(nullptr) { +} + +ParserGzip::~ParserGzip() { + if (m_stream != nullptr) { + finiCompressionStream(m_stream); + m_stream = nullptr; + } +} + +size_t ParserGzip::push(const char *buf, size_t len) { + dbgTrace(D_WAAP_PARSER_GZIP) << "len=" << (unsigned long int)len << ")"; + + if (len == 0) { + dbgTrace(D_WAAP_PARSER_GZIP) << "end of data signal! m_state=" << m_state; + + // flush + if (m_state != s_start) { // only emit if at least something was pushed + if (m_receiver.onKvDone() != 0) { + m_state = s_error; + } + } + + return 0; + } + DecompressionResult res; + switch (m_state) { + case s_start: + dbgTrace(D_WAAP_PARSER_GZIP) << "s_start"; + if (m_receiver.onKey(m_key.data(), m_key.size()) != 0) { + m_state = s_error; + return 0; + } + m_stream = initCompressionStream(); + m_state = s_forward; + // fallthrough // + CP_FALL_THROUGH; + case s_forward: + dbgTrace(D_WAAP_PARSER_GZIP) << "s_forward"; + res = decompressData( + m_stream, + len, + reinterpret_cast(buf)); + dbgTrace(D_WAAP_PARSER_GZIP) << "res: " << res.ok + << ", size: " << res.num_output_bytes + << ", is last: " << res.is_last_chunk; + + if (!res.ok) { + m_state = s_error; + break; + } + + if (res.num_output_bytes != 0 && + m_receiver.onValue(reinterpret_cast(res.output), res.num_output_bytes) != 0) { + m_state = s_error; + break; + } + + if (res.is_last_chunk) { + m_state = s_done; + break; + } + break; + case s_done: + if (len > 0) { + dbgTrace(D_WAAP_PARSER_GZIP) << " unexpected data after completion, len=" << len; + m_state = s_error; + return 0; // Return 0 to indicate error + } + break; + case s_error: + dbgTrace(D_WAAP_PARSER_GZIP) << "s_error"; + return 0; + } + + return len; +} + +void ParserGzip::finish() { + push(NULL, 0); + if (m_state != s_done) { + m_state = s_error; + return; + } +} + +const std::string & +ParserGzip::name() const { + return m_parserName; +} + +bool ParserGzip::error() const { + return m_state == s_error; +} diff --git a/components/security_apps/waap/waap_clib/ParserGzip.h b/components/security_apps/waap/waap_clib/ParserGzip.h new file mode 100755 index 0000000..224e9d0 --- /dev/null +++ b/components/security_apps/waap/waap_clib/ParserGzip.h @@ -0,0 +1,46 @@ +// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __PARSER_GZIP_H_ +#define __PARSER_GZIP_H_ + +#include "ParserBase.h" +#include +#include "compression_utils.h" + +class ParserGzip : public ParserBase { +public: + ParserGzip(IParserStreamReceiver &receiver, size_t parser_depth); + virtual ~ParserGzip(); + size_t push(const char *data, size_t data_len); + void finish(); + virtual const std::string &name() const; + bool error() const; + virtual size_t depth() { return 1; } +private: + enum state { + s_start, + s_forward, + s_done, + s_error + }; + + IParserStreamReceiver &m_receiver; + std::string m_key; + state m_state; + CompressionStream * m_stream; + + static const std::string m_parserName; +}; + +#endif // __PARSER_GZIP_H_ diff --git a/components/security_apps/waap/waap_clib/Serializator.cc b/components/security_apps/waap/waap_clib/Serializator.cc index 578a6a2..362c704 100755 --- a/components/security_apps/waap/waap_clib/Serializator.cc +++ b/components/security_apps/waap/waap_clib/Serializator.cc @@ -44,14 +44,6 @@ static const string defaultSharedStorageHost = "appsec-shared-storage-svc"; #define SHARED_STORAGE_HOST_ENV_NAME "SHARED_STORAGE_HOST" #define LEARNING_HOST_ENV_NAME "LEARNING_HOST" -static bool -isGZipped(const string &stream) -{ - if (stream.size() < 2) return false; - auto unsinged_stream = reinterpret_cast(stream.data()); - return unsinged_stream[0] == 0x1f && unsinged_stream[1] == 0x8b; -} - void yieldIfPossible(const string& func, int line) { // Check if we are in the main loop @@ -73,7 +65,7 @@ bool RestGetFile::loadJson(const string& json) string json_str; json_str = json; - if (!isGZipped(json_str)) + if (!Waap::Util::isGzipped(json_str)) { return ClientRest::loadJson(json_str); } @@ -343,7 +335,7 @@ void SerializeToFileBase::saveData() } string decompress(string fileContent) { - if (!isGZipped(fileContent)) { + if (!Waap::Util::isGzipped(fileContent)) { dbgTrace(D_WAAP_SERIALIZE) << "file note zipped"; return fileContent; } diff --git a/components/security_apps/waap/waap_clib/WaapValueStatsAnalyzer.cc b/components/security_apps/waap/waap_clib/WaapValueStatsAnalyzer.cc index 2e7daf6..f89d9f5 100755 --- a/components/security_apps/waap/waap_clib/WaapValueStatsAnalyzer.cc +++ b/components/security_apps/waap/waap_clib/WaapValueStatsAnalyzer.cc @@ -103,7 +103,7 @@ ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val) bool lastNul = false; // whether last processed character was ASCII NUL size_t curValLength = cur_val.length(); - if (curValLength == 0) { + if (curValLength == 0 || Waap::Util::isGzipped(cur_val)) { canSplitSemicolon = false; canSplitPipe = false; return; diff --git a/components/security_apps/waap/waap_clib/Waf2Util.cc b/components/security_apps/waap/waap_clib/Waf2Util.cc index adf2c08..11d6684 100755 --- a/components/security_apps/waap/waap_clib/Waf2Util.cc +++ b/components/security_apps/waap/waap_clib/Waf2Util.cc @@ -1912,6 +1912,17 @@ base64Decode(const string &input) return out; } +bool +isGzipped(const string &stream) +{ + if (stream.size() < 2) return false; + auto unsinged_stream = reinterpret_cast(stream.data()); + dbgTrace(D_WAAP) << "isGzipped: first two bytes: " + << std::hex << static_cast(unsinged_stream[0]) << " " + << std::hex << static_cast(unsinged_stream[1]); + return unsinged_stream[0] == 0x1f && unsinged_stream[1] == 0x8b; +} + bool containsInvalidUtf8(const string &payload) { diff --git a/components/security_apps/waap/waap_clib/Waf2Util.h b/components/security_apps/waap/waap_clib/Waf2Util.h index 98e3adb..6e2cf22 100755 --- a/components/security_apps/waap/waap_clib/Waf2Util.h +++ b/components/security_apps/waap/waap_clib/Waf2Util.h @@ -1135,6 +1135,7 @@ namespace Util { std::string obfuscateXor(const std::string& toEncrypt); std::string obfuscateXorBase64(const std::string& toEncrypt); + bool isGzipped(const std::string &stream); bool containsInvalidUtf8(const std::string &payload); bool containsPercentEncoding(const std::string &payload); diff --git a/core/include/services_sdk/resources/debug_flags.h b/core/include/services_sdk/resources/debug_flags.h index 51604a3..c15587a 100644 --- a/core/include/services_sdk/resources/debug_flags.h +++ b/core/include/services_sdk/resources/debug_flags.h @@ -106,6 +106,7 @@ DEFINE_FLAG(D_COMPONENT, D_ALL) DEFINE_FLAG(D_WAAP_PARSER_GQL, D_WAAP_PARSER) DEFINE_FLAG(D_WAAP_PARSER_MULTIPART_FORM, D_WAAP_PARSER) DEFINE_FLAG(D_WAAP_PARSER_RAW, D_WAAP_PARSER) + DEFINE_FLAG(D_WAAP_PARSER_GZIP, D_WAAP_PARSER) DEFINE_FLAG(D_WAAP_PARSER_URLENCODE, D_WAAP_PARSER) DEFINE_FLAG(D_WAAP_PARSER_PHPSERIALIZE, D_WAAP_PARSER) DEFINE_FLAG(D_WAAP_PARSER_PERCENT, D_WAAP_PARSER) diff --git a/core/messaging/connection/connection.cc b/core/messaging/connection/connection.cc index ca4322c..b6796e9 100644 --- a/core/messaging/connection/connection.cc +++ b/core/messaging/connection/connection.cc @@ -262,6 +262,29 @@ public: } private: + string + getCertificateDirectory() + { + auto details_ssl_dir = Singleton::Consume::by()->getOpenSSLDir(); + + if (details_ssl_dir.ok()) { + return *details_ssl_dir; + } + + // Use detail_resolver to determine platform-specific certificate directory +#if defined(alpine) + string platform = "alpine"; +#else + string platform = "linux"; +#endif + + if (platform == "alpine") { + return "/etc/ssl/certs/"; + } + + return "/usr/lib/ssl/certs/"; + } + Maybe setSSLContext() { @@ -296,10 +319,11 @@ private: } dbgTrace(D_CONNECTION) << "Setting CA authentication"; - auto details_ssl_dir = Singleton::Consume::by()->getOpenSSLDir(); - auto openssl_dir = details_ssl_dir.ok() ? *details_ssl_dir : "/usr/lib/ssl/certs/"; - auto configured_ssl_dir = getConfigurationWithDefault(openssl_dir, "message", "Trusted CA directory"); - const char *ca_dir = configured_ssl_dir.empty() ? nullptr : configured_ssl_dir.c_str(); + + auto default_ssl_dir = getCertificateDirectory(); + auto configured_ssl_dir = + getProfileAgentSettingWithDefault(default_ssl_dir, "agent.config.message.capath"); + const char *ca_dir = configured_ssl_dir.empty() ? "/usr/lib/ssl/certs/" : configured_ssl_dir.c_str(); if (SSL_CTX_load_verify_locations(ssl_ctx.get(), ca_path.c_str(), ca_dir) != 1) { return genError("Failed to load certificate locations");