mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 11:16:30 +03:00
Mar 13th 2023 update
This commit is contained in:
@@ -27,6 +27,35 @@ USE_DEBUG_FLAG(D_WAAP);
|
||||
|
||||
using namespace std;
|
||||
|
||||
const static string default_host = "open-appsec-tuning-svc";
|
||||
|
||||
void
|
||||
WaapTelemetryBase::sendLog(const LogRest &metric_client_rest) const
|
||||
{
|
||||
OrchestrationMode mode = Singleton::Consume<I_AgentDetails>::by<GenericMetric>()->getOrchestrationMode();
|
||||
|
||||
if (mode == OrchestrationMode::ONLINE) {
|
||||
GenericMetric::sendLog(metric_client_rest);
|
||||
return;
|
||||
}
|
||||
auto svc_host = getConfigurationWithDefault(default_host, "Logging", "K8sSvc Log host");
|
||||
Flags<MessageConnConfig> conn_flags;
|
||||
conn_flags.setFlag(MessageConnConfig::EXTERNAL);
|
||||
string fog_metric_uri = getConfigurationWithDefault<string>("/api/v1/agents/events", "metric", "fogMetricUri");
|
||||
std::string tenant_header = "X-Tenant-Id: " +
|
||||
Singleton::Consume<I_AgentDetails>::by<GenericMetric>()->getTenantId();
|
||||
Singleton::Consume<I_Messaging>::by<GenericMetric>()->sendNoReplyObject(
|
||||
metric_client_rest,
|
||||
I_Messaging::Method::POST,
|
||||
svc_host,
|
||||
80,
|
||||
conn_flags,
|
||||
fog_metric_uri,
|
||||
tenant_header,
|
||||
nullptr,
|
||||
MessageTypeTag::METRIC);
|
||||
}
|
||||
|
||||
void
|
||||
WaapTelemetrics::initMetrics()
|
||||
{
|
||||
@@ -172,7 +201,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
|
||||
"WAAP telemetry",
|
||||
ReportIS::AudienceTeam::WAAP,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
chrono::minutes(10),
|
||||
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||
true,
|
||||
ReportIS::Audience::SECURITY
|
||||
);
|
||||
@@ -204,7 +233,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
|
||||
"WAAP attack type telemetry",
|
||||
ReportIS::AudienceTeam::WAAP,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
chrono::minutes(10),
|
||||
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||
true,
|
||||
ReportIS::Audience::SECURITY
|
||||
);
|
||||
@@ -255,7 +284,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
|
||||
"Waap Metrics",
|
||||
ReportIS::AudienceTeam::WAAP,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
chrono::minutes(10),
|
||||
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||
true,
|
||||
ReportIS::Audience::INTERNAL
|
||||
);
|
||||
@@ -267,7 +296,7 @@ WaapMetricWrapper::upon(const WaapTelemetryEvent &event)
|
||||
"WAAP Attack Type Metrics",
|
||||
ReportIS::AudienceTeam::WAAP,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
chrono::minutes(10),
|
||||
chrono::minutes(LOGGING_INTERVAL_IN_MINUTES),
|
||||
true,
|
||||
ReportIS::Audience::INTERNAL
|
||||
);
|
||||
|
@@ -260,7 +260,6 @@ void TrustedSourcesConfidenceCalculator::log(Key key, Val value, Source source)
|
||||
<< " from the source: "
|
||||
<< source;
|
||||
m_logger[key][value].insert(source);
|
||||
saveData();
|
||||
}
|
||||
|
||||
void TrustedSourcesConfidenceCalculator::reset()
|
||||
|
@@ -16,11 +16,17 @@
|
||||
#include "i_serialize.h"
|
||||
#include "waap.h"
|
||||
|
||||
static const std::string BASE_URI = "/storage/waap/";
|
||||
using namespace std;
|
||||
|
||||
static const string defaultSharedStorageHost = "appsec-shared-storage-svc";
|
||||
|
||||
#define SHARED_STORAGE_HOST_ENV_NAME "SHARED_STORAGE_HOST"
|
||||
USE_DEBUG_FLAG(D_WAAP);
|
||||
|
||||
TuningDecision::TuningDecision(const std::string& remotePath) :
|
||||
m_remotePath(remotePath + "/tuning")
|
||||
TuningDecision::TuningDecision(const string& remotePath)
|
||||
:
|
||||
m_remotePath(remotePath + "/tuning"),
|
||||
m_baseUri()
|
||||
{
|
||||
if (remotePath == "")
|
||||
{
|
||||
@@ -28,7 +34,7 @@ TuningDecision::TuningDecision(const std::string& remotePath) :
|
||||
}
|
||||
Singleton::Consume<I_MainLoop>::by<WaapComponent>()->addRecurringRoutine(
|
||||
I_MainLoop::RoutineType::System,
|
||||
std::chrono::minutes(10),
|
||||
chrono::minutes(10),
|
||||
[&]() { updateDecisions(); },
|
||||
"Get tuning updates"
|
||||
);
|
||||
@@ -48,9 +54,9 @@ struct TuningEvent
|
||||
ar(cereal::make_nvp("eventType", eventType));
|
||||
ar(cereal::make_nvp("eventTitle", eventTitle));
|
||||
}
|
||||
std::string decision;
|
||||
std::string eventType;
|
||||
std::string eventTitle;
|
||||
string decision;
|
||||
string eventType;
|
||||
string eventTitle;
|
||||
};
|
||||
|
||||
class TuningEvents : public RestGetFile
|
||||
@@ -61,16 +67,16 @@ public:
|
||||
|
||||
}
|
||||
|
||||
Maybe<std::vector<TuningEvent>> getTuningEvents()
|
||||
Maybe<vector<TuningEvent>> getTuningEvents()
|
||||
{
|
||||
return decisions.get();
|
||||
}
|
||||
|
||||
private:
|
||||
S2C_PARAM(std::vector<TuningEvent>, decisions);
|
||||
S2C_PARAM(vector<TuningEvent>, decisions);
|
||||
};
|
||||
|
||||
TuningDecisionEnum TuningDecision::convertDecision(std::string decisionStr)
|
||||
TuningDecisionEnum TuningDecision::convertDecision(string decisionStr)
|
||||
{
|
||||
if (decisionStr == "benign")
|
||||
{
|
||||
@@ -87,7 +93,7 @@ TuningDecisionEnum TuningDecision::convertDecision(std::string decisionStr)
|
||||
return NO_DECISION;
|
||||
}
|
||||
|
||||
TuningDecisionType TuningDecision::convertDecisionType(std::string decisionTypeStr)
|
||||
TuningDecisionType TuningDecision::convertDecisionType(string decisionTypeStr)
|
||||
{
|
||||
if (decisionTypeStr == "source")
|
||||
{
|
||||
@@ -112,9 +118,18 @@ void TuningDecision::updateDecisions()
|
||||
{
|
||||
TuningEvents tuningEvents;
|
||||
RemoteFilesList tuningDecisionFiles;
|
||||
if (m_baseUri == "") {
|
||||
I_AgentDetails *agentDetails = Singleton::Consume<I_AgentDetails>::by<WaapComponent>();
|
||||
if (agentDetails->getOrchestrationMode() != OrchestrationMode::ONLINE) {
|
||||
m_baseUri = "/api/";
|
||||
} else {
|
||||
m_baseUri = "/storage/waap/";
|
||||
}
|
||||
dbgTrace(D_WAAP) << "URI prefix: " << m_baseUri;
|
||||
}
|
||||
bool isSuccessful = sendObject(tuningDecisionFiles,
|
||||
I_Messaging::Method::GET,
|
||||
BASE_URI + "?list-type=2&prefix=" + m_remotePath);
|
||||
m_baseUri + "?list-type=2&prefix=" + m_remotePath);
|
||||
|
||||
if (!isSuccessful || tuningDecisionFiles.getFilesList().empty())
|
||||
{
|
||||
@@ -124,12 +139,12 @@ void TuningDecision::updateDecisions()
|
||||
|
||||
if (!sendObject(tuningEvents,
|
||||
I_Messaging::Method::GET,
|
||||
BASE_URI + tuningDecisionFiles.getFilesList()[0]))
|
||||
m_baseUri + tuningDecisionFiles.getFilesList()[0]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_decisions.clear();
|
||||
Maybe<std::vector<TuningEvent>> events = tuningEvents.getTuningEvents();
|
||||
Maybe<vector<TuningEvent>> events = tuningEvents.getTuningEvents();
|
||||
if (!events.ok())
|
||||
{
|
||||
dbgDebug(D_WAAP) << "failed to parse events";
|
||||
@@ -142,7 +157,7 @@ void TuningDecision::updateDecisions()
|
||||
}
|
||||
}
|
||||
|
||||
TuningDecisionEnum TuningDecision::getDecision(std::string tuningValue, TuningDecisionType tuningType)
|
||||
TuningDecisionEnum TuningDecision::getDecision(string tuningValue, TuningDecisionType tuningType)
|
||||
{
|
||||
const auto& typeDecisionsItr = m_decisions.find(tuningType);
|
||||
if (typeDecisionsItr == m_decisions.cend())
|
||||
@@ -156,3 +171,20 @@ TuningDecisionEnum TuningDecision::getDecision(std::string tuningValue, TuningDe
|
||||
}
|
||||
return decisionItr->second;
|
||||
}
|
||||
|
||||
string
|
||||
TuningDecision::getSharedStorageHost()
|
||||
{
|
||||
static string shared_storage_host;
|
||||
if (!shared_storage_host.empty()) {
|
||||
return shared_storage_host;
|
||||
}
|
||||
char* sharedStorageHost = getenv(SHARED_STORAGE_HOST_ENV_NAME);
|
||||
if (sharedStorageHost != NULL) {
|
||||
shared_storage_host = string(sharedStorageHost);
|
||||
dbgInfo(D_WAAP) << "shared storage host is set to " << shared_storage_host;
|
||||
return shared_storage_host;
|
||||
}
|
||||
dbgWarning(D_WAAP) << "shared storage host is not set. using default: " << defaultSharedStorageHost;
|
||||
return defaultSharedStorageHost;
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ private:
|
||||
void updateDecisions();
|
||||
TuningDecisionType convertDecisionType(std::string decisionTypeStr);
|
||||
TuningDecisionEnum convertDecision(std::string decisionStr);
|
||||
|
||||
std::string getSharedStorageHost();
|
||||
|
||||
template<typename T>
|
||||
bool sendObject(T &obj, I_Messaging::Method method, std::string uri)
|
||||
@@ -64,7 +64,7 @@ private:
|
||||
return messaging->sendObject(
|
||||
obj,
|
||||
method,
|
||||
"fog-msrv-appsec-shared-files-svc",
|
||||
getSharedStorageHost(),
|
||||
80,
|
||||
conn_flags,
|
||||
uri,
|
||||
@@ -83,6 +83,7 @@ private:
|
||||
}
|
||||
|
||||
std::string m_remotePath;
|
||||
std::string m_baseUri;
|
||||
std::map<TuningDecisionType, std::map<std::string, TuningDecisionEnum>> m_decisions;
|
||||
};
|
||||
|
||||
|
@@ -24,6 +24,7 @@ bool checkUrlEncoded(const char *buf, size_t len)
|
||||
dbgFlow(D_WAAP);
|
||||
size_t i = 0;
|
||||
int hex_characters_to_follow = 0;
|
||||
bool has_encoded_value = false;
|
||||
|
||||
for (; i < len; i++) {
|
||||
char ch = buf[i];
|
||||
@@ -38,6 +39,7 @@ bool checkUrlEncoded(const char *buf, size_t len)
|
||||
}
|
||||
return false;
|
||||
} else if (ch == '%') {
|
||||
has_encoded_value = true;
|
||||
hex_characters_to_follow = 2;
|
||||
continue;
|
||||
}
|
||||
@@ -75,7 +77,7 @@ bool checkUrlEncoded(const char *buf, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return has_encoded_value;
|
||||
}
|
||||
|
||||
ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
|
||||
@@ -139,6 +141,10 @@ ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
|
||||
break;
|
||||
}
|
||||
|
||||
if (isspace(ch)) {
|
||||
hasSpace = true;
|
||||
}
|
||||
|
||||
// The index will be 0 for even, and 1 for odd offsets
|
||||
int index = i % 2;
|
||||
|
||||
@@ -225,40 +231,6 @@ ValueStatsAnalyzer::ValueStatsAnalyzer(const std::string &cur_val)
|
||||
if (longestZerosSeq[0] <= 2 && longestZerosSeq[1] <= 2) {
|
||||
isUTF16 = false;
|
||||
}
|
||||
|
||||
// Detect URLEncode value
|
||||
size_t ofs = 0;
|
||||
for (size_t i = 0 ; i < cur_val.size(); ++i) {
|
||||
char ch = cur_val[i];
|
||||
|
||||
if (isspace(ch)) {
|
||||
hasSpace = true;
|
||||
isUrlEncoded = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ofs == 0) {
|
||||
if (ch == '%') {
|
||||
ofs++;
|
||||
}
|
||||
}
|
||||
else if (ofs <= 2) {
|
||||
if (!isHexDigit(ch)) {
|
||||
isUrlEncoded = false;
|
||||
break; // at least one broken URLEncode sequence detected
|
||||
}
|
||||
if (ofs == 2) {
|
||||
isUrlEncoded = true; // complete '%hh' sequence
|
||||
ofs = 0; // search for next '%' character
|
||||
}
|
||||
else {
|
||||
ofs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel url decoding if partial match after '%' is found, or if potential specific utf8 evasion is suspected
|
||||
if (ofs != 0) {
|
||||
isUrlEncoded = false;
|
||||
}
|
||||
isUrlEncoded = checkUrlEncoded(cur_val.data(), cur_val.size());
|
||||
}
|
||||
|
Reference in New Issue
Block a user