mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 19:24:26 +03:00
My 11th 2023 update
This commit is contained in:
7
components/security_apps/ips/ips_ut/CMakeLists.txt
Normal file
7
components/security_apps/ips/ips_ut/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
link_directories(${CMAKE_BINARY_DIR}/core/shmem_ipc)
|
||||
|
||||
add_unit_test(
|
||||
ips_ut
|
||||
"signatures_ut.cc;entry_ut.cc;component_ut.cc;configuration.cc;rule_selector_ut.cc;compound_ut.cc;resource_ut.cc"
|
||||
"ips;keywords;pcre2-8;intelligence_is_v2;logging;compression_utils;agent_details;time_proxy;event_is;table;http_transaction_data;nginx_attachment;connkey;pm;metric;encryptor;generic_rulebase;generic_rulebase_evaluators;compression_utils;ip_utilities;-lboost_regex;-lcrypto;-lz"
|
||||
)
|
913
components/security_apps/ips/ips_ut/component_ut.cc
Normal file
913
components/security_apps/ips/ips_ut/component_ut.cc
Normal file
@@ -0,0 +1,913 @@
|
||||
#include "ips_comp.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "cptest.h"
|
||||
#include "ips_entry.h"
|
||||
#include "new_table_entry.h"
|
||||
#include "keyword_comp.h"
|
||||
#include "environment.h"
|
||||
#include "mock/mock_table.h"
|
||||
#include "config.h"
|
||||
#include "http_manager.h"
|
||||
#include "config_component.h"
|
||||
#include "agent_details.h"
|
||||
#include "mock/mock_logging.h"
|
||||
#include "mock/mock_time_get.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "encryptor.h"
|
||||
#include "generic_rulebase/generic_rulebase.h"
|
||||
#include "generic_rulebase/triggers_config.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
class ComponentTest : public Test
|
||||
{
|
||||
public:
|
||||
ComponentTest()
|
||||
{
|
||||
comp.preload();
|
||||
comp.init();
|
||||
}
|
||||
|
||||
~ComponentTest()
|
||||
{
|
||||
comp.fini();
|
||||
}
|
||||
|
||||
void
|
||||
loadPolicy(const string &config)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << config;
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(ss);
|
||||
}
|
||||
|
||||
void
|
||||
setTrigger()
|
||||
{
|
||||
string log_trigger(
|
||||
"{"
|
||||
" \"context\": \"triggerId(5eaeefde6765c30010bae8b6)\","
|
||||
" \"triggerName\": \"Logging Trigger\","
|
||||
" \"triggerType\": \"log\","
|
||||
" \"urlForSyslog\": \"\","
|
||||
" \"urlForCef\": \"128.1.1.1:333\","
|
||||
" \"acAllow\": false,"
|
||||
" \"acDrop\": true,"
|
||||
" \"complianceViolations\": true,"
|
||||
" \"complianceWarnings\": true,"
|
||||
" \"logToAgent\": true,"
|
||||
" \"logToCloud\": true,"
|
||||
" \"logToSyslog\": false,"
|
||||
" \"logToCef\": true,"
|
||||
" \"tpDetect\": true,"
|
||||
" \"tpPrevent\": true,"
|
||||
" \"verbosity\": \"Standard\","
|
||||
" \"webBody\": true,"
|
||||
" \"webHeaders\": true,"
|
||||
" \"webRequests\": true,"
|
||||
" \"webUrlPath\": true,"
|
||||
" \"webUrlQuery\": true"
|
||||
"}"
|
||||
);
|
||||
|
||||
stringstream ss(log_trigger);
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
LogTriggerConf trigger;
|
||||
trigger.load(ar);
|
||||
|
||||
setConfiguration(trigger, "rulebase", "log");
|
||||
}
|
||||
|
||||
IPSComp comp;
|
||||
StrictMock<MockTable> table;
|
||||
IPSEntry entry;
|
||||
|
||||
GenericRulebase generic_rulebase;
|
||||
ConfigComponent conf;
|
||||
Encryptor encryptor;
|
||||
KeywordComp keywords;
|
||||
::Environment env;
|
||||
AgentDetails details;
|
||||
NiceMock<MockLogging> logs;
|
||||
NiceMock<MockTimeGet> time;
|
||||
NiceMock<MockMainLoop> mainloop;
|
||||
static const EventVerdict inspect;
|
||||
static const EventVerdict accept;
|
||||
static const EventVerdict drop;
|
||||
|
||||
HttpHeader end_headers{Buffer(""), Buffer(""), 0, true};
|
||||
};
|
||||
|
||||
static bool
|
||||
operator ==(const EventVerdict &first, const EventVerdict &second)
|
||||
{
|
||||
return first.getVerdict() == second.getVerdict();
|
||||
}
|
||||
|
||||
const EventVerdict ComponentTest::inspect(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT);
|
||||
|
||||
const EventVerdict ComponentTest::accept(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT);
|
||||
|
||||
const EventVerdict ComponentTest::drop(ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP);
|
||||
|
||||
TEST_F(ComponentTest, check_init_fini_do_not_crush)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, new_table_entry_with_empty_configuration)
|
||||
{
|
||||
NewTableEntry().notify();
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, new_table_entry_with_configuration)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"configurations\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"contextsConfiguration\": ["
|
||||
"{"
|
||||
"\"type\": \"keep\","
|
||||
"\"name\": \"HTTP_REQUEST_BODY\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"],"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Prevent\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
loadPolicy(config);
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillOnce(Return(&entry));
|
||||
NewTableEntry().notify();
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, events)
|
||||
{
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
IPSEntry entry;
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
|
||||
HttpTransactionData transaction;
|
||||
EXPECT_THAT(NewHttpTransactionEvent(transaction).query(), ElementsAre(accept));
|
||||
HttpHeader header_req(Buffer("key"), Buffer("val"), 1);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req).query(), ElementsAre(inspect));
|
||||
HttpBody body_req(Buffer("data"), 0, true);
|
||||
EXPECT_THAT(HttpRequestBodyEvent(body_req, Buffer()).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(accept));
|
||||
|
||||
EXPECT_THAT(ResponseCodeEvent(200).query(), ElementsAre(inspect));
|
||||
HttpHeader header_res(Buffer("key"), Buffer("val"), 2);
|
||||
EXPECT_THAT(HttpResponseHeaderEvent(header_res).query(), ElementsAre(inspect));
|
||||
HttpBody body_res(Buffer("data"), true, 0);
|
||||
EXPECT_THAT(HttpResponseBodyEvent(body_res, Buffer()).query(), ElementsAre(accept));
|
||||
EXPECT_THAT(EndTransactionEvent().performNamedQuery(), ElementsAre(Pair("ips application", accept)));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, check_url_decoding)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"d d\\\";\","
|
||||
"\"context\": [\"HTTP_COMPLETE_URL_DECODED\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Prevent\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"GET",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(end_headers).query(), ElementsAre(drop));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(drop));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, check_query)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"g=#\\\";\","
|
||||
"\"context\": [\"HTTP_QUERY_DECODED\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Prevent\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"GET",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(end_headers).query(), ElementsAre(drop));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(drop));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, check_query_detect_mode)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"d d\\\";\","
|
||||
"\"context\": [\"HTTP_QUERY_DECODED\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Detect\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillOnce(Return(&entry));
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"GET",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(EndTransactionEvent().query(), ElementsAre(accept));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, check_query_inactive_mode)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"g=#\\\";\","
|
||||
"\"context\": [\"HTTP_QUERY_DECODED\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Prevent\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Inactive\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"GET",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(accept));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, check_query_silent_mode)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"silent\": true,"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"g=#\\\";\","
|
||||
"\"context\": [\"HTTP_QUERY_DECODED\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Prevent\","
|
||||
"\"rules\": []"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"GET",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(end_headers).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(accept));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, check_filtering_by_year)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [ \"ggg\", \"Threat_Year_2014\", \"hhh\" ],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"g=#\\\";\","
|
||||
"\"context\": [\"HTTP_QUERY_DECODED\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Prevent\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Inactive\","
|
||||
"\"protectionsFromYear\": 2013"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"GET",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(accept));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, log_fields)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"Max Field Size\": ["
|
||||
"{"
|
||||
"\"value\": 25"
|
||||
"}"
|
||||
"],"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Prevent\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
setTrigger();
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
|
||||
Report report;
|
||||
EXPECT_CALL(logs, sendLog(_)).WillOnce(SaveArg<0>(&report));
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"POST",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
HttpHeader header_req1(Buffer("key1"), Buffer("val1"), 1);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req1).query(), ElementsAre(inspect));
|
||||
HttpHeader header_req2(Buffer("key2"), Buffer("val2"), 2);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req2).query(), ElementsAre(inspect));
|
||||
HttpHeader header_req3(Buffer("key3"), Buffer("val3"), 3);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req3).query(), ElementsAre(inspect));
|
||||
string body_str("data: ddd");
|
||||
HttpBody body_req(Buffer(body_str), 0, true);
|
||||
EXPECT_THAT(HttpRequestBodyEvent(body_req, Buffer()).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(drop));
|
||||
|
||||
EXPECT_THAT(report.getSyslog(), HasSubstr("httpRequestHeaders=\"key1: val1, key2: val2\""));
|
||||
EXPECT_THAT(report.getSyslog(), HasSubstr("httpRequestBody=\"" + body_str + "\""));
|
||||
EXPECT_THAT(report.getSyslog(), HasSubstr("signatureVersion=\"20210420\""));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, log_field_httpRequestHeader)
|
||||
{
|
||||
string config =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"Max Field Size\": ["
|
||||
"{"
|
||||
"\"value\": 25"
|
||||
"}"
|
||||
"],"
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}"
|
||||
"],"
|
||||
"\"IpsProtections\": ["
|
||||
"{"
|
||||
"\"context\": \"\","
|
||||
"\"ruleName\": \"rule1\","
|
||||
"\"assetName\": \"asset1\","
|
||||
"\"assetId\": \"1-1-1\","
|
||||
"\"practiceId\": \"2-2-2\","
|
||||
"\"practiceName\": \"practice1\","
|
||||
"\"defaultAction\": \"Detect\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Prevent\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"performanceImpact\": \"High or lower\","
|
||||
"\"confidenceLevel\": \"Low\""
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
setTrigger();
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
IPSEntry entry;
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
|
||||
Report report;
|
||||
EXPECT_CALL(logs, sendLog(_)).WillOnce(SaveArg<0>(&report));
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"POST",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
HttpHeader header_req1(Buffer("key1"), Buffer("val1"), 1);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req1).query(), ElementsAre(inspect));
|
||||
HttpBody body_req(Buffer("data: ddd"), 0, true);
|
||||
EXPECT_THAT(HttpRequestBodyEvent(body_req, Buffer()).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(drop));
|
||||
|
||||
EXPECT_THAT(report.getSyslog(), HasSubstr("httpRequestHeaders=\"key1: val1\""));
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
IPSEntry entry1;
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry1));
|
||||
Report report1;
|
||||
EXPECT_CALL(logs, sendLog(_)).WillOnce(SaveArg<0>(&report1));
|
||||
|
||||
HttpTransactionData new_transaction2(
|
||||
"1.1",
|
||||
"POST",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"d%20d?g=%23",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction2).query(), ElementsAre(inspect));
|
||||
HttpHeader header_req2(Buffer("key2"), Buffer("val2"), 1);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req2).query(), ElementsAre(inspect));
|
||||
|
||||
HttpBody body_req2(Buffer("data: ddd"), 0, true);
|
||||
EXPECT_THAT(HttpRequestBodyEvent(body_req2, Buffer()).query(), ElementsAre(inspect));
|
||||
EXPECT_THAT(EndRequestEvent().query(), ElementsAre(drop));
|
||||
|
||||
EXPECT_THAT(report1.getSyslog(), HasSubstr("httpRequestHeaders=\"key2: val2\""));
|
||||
}
|
||||
|
||||
TEST_F(ComponentTest, prxeem_exception_bug)
|
||||
{
|
||||
generic_rulebase.preload();
|
||||
generic_rulebase.init();
|
||||
string config =
|
||||
"{"
|
||||
" \"IPS\": {"
|
||||
" \"protections\": ["
|
||||
" {"
|
||||
" \"protectionMetadata\": {"
|
||||
" \"protectionName\": \"Null HTTP Encodings\","
|
||||
" \"maintrainId\": \"101\","
|
||||
" \"severity\": \"Low\","
|
||||
" \"confidenceLevel\": \"Low\","
|
||||
" \"performanceImpact\": \"Medium High\","
|
||||
" \"lastUpdate\": \"20210420\","
|
||||
" \"tags\": [],"
|
||||
" \"cveList\": []"
|
||||
" },"
|
||||
" \"detectionRules\": {"
|
||||
" \"type\": \"simple\","
|
||||
" \"SSM\": \"\","
|
||||
" \"keywords\": \"data: \\\"|25|00\\\"; data: \\\"?\\\";\","
|
||||
" \"context\": [\"HTTP_COMPLETE_URL_ENCODED\"]"
|
||||
" }"
|
||||
" }"
|
||||
" ],"
|
||||
" \"IpsProtections\": ["
|
||||
" {"
|
||||
" \"context\": \"\","
|
||||
" \"ruleName\": \"rule1\","
|
||||
" \"assetName\": \"asset1\","
|
||||
" \"assetId\": \"1-1-1\","
|
||||
" \"practiceId\": \"2-2-2\","
|
||||
" \"practiceName\": \"practice1\","
|
||||
" \"defaultAction\": \"Prevent\","
|
||||
" \"rules\": []"
|
||||
" }"
|
||||
" ]"
|
||||
" },"
|
||||
" \"rulebase\": {"
|
||||
" \"rulesConfig\": ["
|
||||
" {"
|
||||
" \"context\": \"All()\","
|
||||
" \"priority\": 1,"
|
||||
" \"ruleId\": \"5eaef0726765c30010bae8bb\","
|
||||
" \"ruleName\": \"Acme web API\","
|
||||
" \"assetId\": \"5e243effd858007660b758ad\","
|
||||
" \"assetName\": \"Acme Power API\","
|
||||
" \"parameters\": ["
|
||||
" {"
|
||||
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764003\","
|
||||
" \"parameterType\": \"exceptions\","
|
||||
" \"parameterName\": \"exception\""
|
||||
" }"
|
||||
" ],"
|
||||
" \"zoneId\": \"\","
|
||||
" \"zoneName\": \"\""
|
||||
" }"
|
||||
" ],"
|
||||
" \"exception\": ["
|
||||
" {"
|
||||
" \"context\": \"parameterId(6c3867be-4da5-42c2-93dc-8f509a764003)\","
|
||||
" \"match\": {"
|
||||
" \"type\": \"operator\","
|
||||
" \"op\": \"and\","
|
||||
" \"items\": [{"
|
||||
" \"type\": \"condition\","
|
||||
" \"op\": \"equals\","
|
||||
" \"key\": \"url\","
|
||||
" \"value\": [\"(/en|/de)?/admin/helpdesk/dashboard/operator/advanced_search.*\"]"
|
||||
" }, {"
|
||||
" \"type\": \"operator\","
|
||||
" \"op\": \"or\","
|
||||
" \"items\": [{"
|
||||
" \"type\": \"condition\","
|
||||
" \"op\": \"equals\","
|
||||
" \"key\": \"protectionName\","
|
||||
" \"value\": [\"Null HTTP Encodings\"]"
|
||||
" }, {"
|
||||
" \"type\": \"condition\","
|
||||
" \"op\": \"equals\","
|
||||
" \"key\": \"parameterName\","
|
||||
" \"value\": [\"op\\\\.submit\\\\.reset\"]"
|
||||
" }]"
|
||||
" }]"
|
||||
" },"
|
||||
" \"behavior\": {"
|
||||
" \"key\": \"action\","
|
||||
" \"value\": \"accept\""
|
||||
" }"
|
||||
" }"
|
||||
" ]"
|
||||
" }"
|
||||
"}";
|
||||
loadPolicy(config);
|
||||
|
||||
|
||||
EXPECT_CALL(table, createStateRValueRemoved(_, _));
|
||||
IPSEntry entry;
|
||||
EXPECT_CALL(table, getState(_)).WillRepeatedly(Return(&entry));
|
||||
EXPECT_CALL(table, hasState(_)).WillRepeatedly(Return(true));
|
||||
|
||||
HttpTransactionData new_transaction(
|
||||
"1.1",
|
||||
"POST",
|
||||
"ffff",
|
||||
IPAddr::createIPAddr("0.0.0.0").unpack(),
|
||||
80,
|
||||
"/admin/helpdesk/dashboard/operator/advanced_search?order=created&stuff=%00",
|
||||
IPAddr::createIPAddr("1.1.1.1").unpack(),
|
||||
5428
|
||||
);
|
||||
|
||||
EXPECT_THAT(NewHttpTransactionEvent(new_transaction).query(), ElementsAre(inspect));
|
||||
HttpHeader header_req1(Buffer("key1"), Buffer("val1"), 0, true);
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header_req1).query(), ElementsAre(inspect));
|
||||
}
|
155
components/security_apps/ips/ips_ut/compound_ut.cc
Normal file
155
components/security_apps/ips/ips_ut/compound_ut.cc
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "compound_protection.h"
|
||||
|
||||
#include "cptest.h"
|
||||
#include "ips_entry.h"
|
||||
#include "mock/mock_table.h"
|
||||
#include "environment.h"
|
||||
#include "i_keywords_rule.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
class CompoundTest : public Test
|
||||
{
|
||||
public:
|
||||
CompoundTest()
|
||||
{
|
||||
ON_CALL(table, hasState(_)).WillByDefault(Return(true));
|
||||
ON_CALL(table, getState(_)).WillByDefault(Return(&ips_state));
|
||||
}
|
||||
|
||||
template <typename ... PatternContextPair>
|
||||
shared_ptr<IPSSignatureSubTypes::BaseSignature>
|
||||
loadSig(const string &name, const string &operation, PatternContextPair ... pat_ctx)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "{"
|
||||
<< "\"type\": \"compound\","
|
||||
<< "\"operation\": \"" << operation << "\","
|
||||
<< "\"operands\": [";
|
||||
getSginatureStream(ss, pat_ctx ...);
|
||||
ss << "]" << "}";
|
||||
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
|
||||
return CompoundProtection::get(name, ar);
|
||||
}
|
||||
|
||||
template <typename ... Strings>
|
||||
set<PMPattern>
|
||||
turnToPatternSet(const Strings & ... strings)
|
||||
{
|
||||
pat_set.clear();
|
||||
populatePatternSet(strings ...);
|
||||
return pat_set;
|
||||
}
|
||||
|
||||
void setActiveContext(const string &name) { ctx.registerValue(I_KeywordsRule::getKeywordsRuleTag(), name); }
|
||||
|
||||
private:
|
||||
void populatePatternSet() {}
|
||||
|
||||
template <typename ... Strings>
|
||||
void
|
||||
populatePatternSet(const string &pat, const Strings & ... strings)
|
||||
{
|
||||
pat_set.emplace(pat, false, false);
|
||||
populatePatternSet(strings ...);
|
||||
}
|
||||
|
||||
ostream &
|
||||
getSginatureStream(ostream &ss, const string &pattern, const string &context)
|
||||
{
|
||||
ss << "{"
|
||||
<< "\"type\": \"simple\","
|
||||
<< "\"SSM\": \"" << pattern << "\","
|
||||
<< "\"keywords\": \"\","
|
||||
<< "\"context\": ["
|
||||
<< "\"" << context << "\""
|
||||
<< "]"
|
||||
<< "}";
|
||||
return ss;
|
||||
}
|
||||
|
||||
template <typename ... PatternContextPair>
|
||||
ostream &
|
||||
getSginatureStream(ostream &ss, const string &pattern, const string &context, PatternContextPair ... pat_ctx)
|
||||
{
|
||||
return getSginatureStream(getSginatureStream(ss, pattern, context) << ",", pat_ctx ...);
|
||||
}
|
||||
|
||||
NiceMock<MockTable> table;
|
||||
IPSEntry ips_state;
|
||||
set<PMPattern> pat_set;
|
||||
::Environment env;
|
||||
ScopedContext ctx;
|
||||
};
|
||||
|
||||
TEST_F(CompoundTest, BasicLoading)
|
||||
{
|
||||
auto sig = loadSig("Test", "and", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
EXPECT_NE(sig, nullptr);
|
||||
EXPECT_EQ(sig->getSigId(), "Test");
|
||||
EXPECT_THAT(sig->getContext(), ElementsAre("HTTP_REQUEST_DATA", "HTTP_RESPONSE_DATA"));
|
||||
EXPECT_EQ(sig->patternsInSignature(), turnToPatternSet("aaa", "bbb"));
|
||||
}
|
||||
|
||||
TEST_F(CompoundTest, BasicOrTest)
|
||||
{
|
||||
auto sig = loadSig("Test", "or", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
|
||||
setActiveContext("NO_CONTEXT");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("aaa")), IPSSignatureSubTypes::BaseSignature::MatchType::NO_MATCH);
|
||||
setActiveContext("HTTP_REQUEST_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("aaa")), IPSSignatureSubTypes::BaseSignature::MatchType::MATCH);
|
||||
setActiveContext("HTTP_REQUEST_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("ddd")), IPSSignatureSubTypes::BaseSignature::MatchType::CACHE_MATCH);
|
||||
}
|
||||
|
||||
TEST_F(CompoundTest, BasicOrOrderTest)
|
||||
{
|
||||
auto sig = loadSig("Test", "or", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
|
||||
setActiveContext("HTTP_RESPONSE_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("bbb")), IPSSignatureSubTypes::BaseSignature::MatchType::MATCH);
|
||||
}
|
||||
|
||||
TEST_F(CompoundTest, BasicAndTest)
|
||||
{
|
||||
auto sig = loadSig("Test", "and", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
|
||||
setActiveContext("HTTP_REQUEST_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("aaa")), IPSSignatureSubTypes::BaseSignature::MatchType::NO_MATCH);
|
||||
setActiveContext("HTTP_RESPONSE_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("bbb")), IPSSignatureSubTypes::BaseSignature::MatchType::MATCH);
|
||||
}
|
||||
|
||||
TEST_F(CompoundTest, BasicAndOrderTest)
|
||||
{
|
||||
auto sig = loadSig("Test", "and", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
|
||||
setActiveContext("HTTP_RESPONSE_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("bbb")), IPSSignatureSubTypes::BaseSignature::MatchType::NO_MATCH);
|
||||
setActiveContext("HTTP_REQUEST_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("aaa")), IPSSignatureSubTypes::BaseSignature::MatchType::MATCH);
|
||||
}
|
||||
|
||||
TEST_F(CompoundTest, BasicOrderedAndTest)
|
||||
{
|
||||
auto sig = loadSig("Test", "ordered_and", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
|
||||
setActiveContext("HTTP_REQUEST_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("aaa")), IPSSignatureSubTypes::BaseSignature::MatchType::NO_MATCH);
|
||||
setActiveContext("HTTP_RESPONSE_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("bbb")), IPSSignatureSubTypes::BaseSignature::MatchType::MATCH);
|
||||
}
|
||||
|
||||
TEST_F(CompoundTest, BasicOrderedAndOrderTest)
|
||||
{
|
||||
auto sig = loadSig("Test", "ordered_and", "aaa", "HTTP_REQUEST_DATA", "bbb", "HTTP_RESPONSE_DATA");
|
||||
|
||||
setActiveContext("HTTP_RESPONSE_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("bbb")), IPSSignatureSubTypes::BaseSignature::MatchType::NO_MATCH);
|
||||
setActiveContext("HTTP_REQUEST_DATA");
|
||||
EXPECT_EQ(sig->getMatch(turnToPatternSet("aaa")), IPSSignatureSubTypes::BaseSignature::MatchType::NO_MATCH);
|
||||
}
|
55
components/security_apps/ips/ips_ut/configuration.cc
Normal file
55
components/security_apps/ips/ips_ut/configuration.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "ips_configuration.h"
|
||||
#include "cptest.h"
|
||||
|
||||
TEST(configuration, basic_context)
|
||||
{
|
||||
cptestPrepareToDie();
|
||||
|
||||
IPSConfiguration::Context ctx1(IPSConfiguration::ContextType::HISTORY, 254);
|
||||
EXPECT_EQ(ctx1.getType(), IPSConfiguration::ContextType::HISTORY);
|
||||
EXPECT_EQ(ctx1.getHistorySize(), 254);
|
||||
|
||||
IPSConfiguration::Context ctx2(IPSConfiguration::ContextType::NORMAL, 0);
|
||||
EXPECT_EQ(ctx2.getType(), IPSConfiguration::ContextType::NORMAL);
|
||||
EXPECT_DEATH(ctx2.getHistorySize(), "Try to access history size for non-history context");
|
||||
}
|
||||
|
||||
|
||||
TEST(configuration, read_configuration)
|
||||
{
|
||||
cptestPrepareToDie();
|
||||
|
||||
std::stringstream conf_str;
|
||||
conf_str <<
|
||||
"{"
|
||||
"\"contextsConfiguration\": ["
|
||||
"{"
|
||||
"\"name\": \"HTTP_REQUEST_BODY\","
|
||||
"\"type\": \"history\","
|
||||
"\"historySize\": 100"
|
||||
"},"
|
||||
"{"
|
||||
"\"name\": \"HTTP_REQUEST_HEADER\","
|
||||
"\"type\": \"keep\""
|
||||
"}"
|
||||
"]"
|
||||
"}";
|
||||
|
||||
cereal::JSONInputArchive ar(conf_str);
|
||||
|
||||
IPSConfiguration conf;
|
||||
conf.load(ar);
|
||||
|
||||
auto body = conf.getContext("HTTP_REQUEST_BODY");
|
||||
EXPECT_EQ(body.getType(), IPSConfiguration::ContextType::HISTORY);
|
||||
EXPECT_EQ(conf.getHistorySize("HTTP_REQUEST_BODY"), 100);
|
||||
|
||||
auto header = conf.getContext("HTTP_REQUEST_HEADER");
|
||||
EXPECT_EQ(header.getType(), IPSConfiguration::ContextType::KEEP);
|
||||
EXPECT_DEATH(conf.getHistorySize("HTTP_REQUEST_HEADER"), "Try to access history size for non-history context");
|
||||
|
||||
auto line = conf.getContext("HTTP_REQUEST_LINE");
|
||||
EXPECT_EQ(line.getType(), IPSConfiguration::ContextType::NORMAL);
|
||||
|
||||
EXPECT_DEATH(conf.getHistorySize("NO_CONTEXT"), "Try to access history size for non-exiting context");
|
||||
}
|
268
components/security_apps/ips/ips_ut/entry_ut.cc
Normal file
268
components/security_apps/ips/ips_ut/entry_ut.cc
Normal file
@@ -0,0 +1,268 @@
|
||||
#include "ips_entry.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "ips_signatures.h"
|
||||
#include "cptest.h"
|
||||
#include "keyword_comp.h"
|
||||
#include "config.h"
|
||||
#include "config_component.h"
|
||||
#include "environment.h"
|
||||
#include "agent_details.h"
|
||||
#include "mock/mock_logging.h"
|
||||
#include "mock/mock_time_get.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "mock/mock_table.h"
|
||||
#include "generic_rulebase/generic_rulebase.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const ParsedContextReply &action)
|
||||
{
|
||||
return os << (action==ParsedContextReply::ACCEPT ? "ACCEPT" : "DROP");
|
||||
}
|
||||
|
||||
class MockAgg : Singleton::Provide<I_FirstTierAgg>::SelfInterface
|
||||
{
|
||||
shared_ptr<PMHook>
|
||||
getHook(const string &, const set<PMPattern> &pats) override
|
||||
{
|
||||
auto hook = make_shared<PMHook>();
|
||||
hook->prepare(pats);
|
||||
return hook;
|
||||
}
|
||||
};
|
||||
|
||||
class EntryTest : public Test
|
||||
{
|
||||
public:
|
||||
EntryTest()
|
||||
{
|
||||
ON_CALL(table, getState(_)).WillByDefault(Return(ptr));
|
||||
}
|
||||
|
||||
void
|
||||
loadSignatures(const string &sigs)
|
||||
{
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << sigs << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
IPSSignaturesResource resource;
|
||||
resource.load(ar);
|
||||
setResource(resource, "IPS", "protections");
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "{";
|
||||
ss << "\"context\": \"\",";
|
||||
ss << "\"ruleName\": \"rule1\",";
|
||||
ss << "\"assetName\": \"asset1\",";
|
||||
ss << "\"assetId\": \"1-1-1\",";
|
||||
ss << "\"practiceId\": \"2-2-2\",";
|
||||
ss << "\"practiceName\": \"practice1\",";
|
||||
ss << "\"defaultAction\": \"Detect\",";
|
||||
ss << "\"rules\": [";
|
||||
ss << "{";
|
||||
ss << "\"action\": \"Prevent\",";
|
||||
ss << "\"performanceImpact\": \"High or lower\",";
|
||||
ss << "\"severityLevel\": \"Low or above\",";
|
||||
ss << "\"confidenceLevel\": \"Low\"";
|
||||
ss << "}";
|
||||
ss << "]";
|
||||
ss << "}";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
IPSSignatures signatures;
|
||||
signatures.load(ar);
|
||||
setConfiguration(signatures, "IPS", "IpsProtections");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
loadSnortSignatures(const string &sigs)
|
||||
{
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[{ \"modificationTime\": \"22/02/08\", \"name\": \"rules1\", \"protections\": [" << sigs << "] }]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
SnortSignaturesResource resource;
|
||||
resource.load(ar);
|
||||
setResource(resource, "IPSSnortSigs", "protections");
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "{";
|
||||
ss << "\"context\": \"\",";
|
||||
ss << "\"assetName\": \"asset1\",";
|
||||
ss << "\"assetId\": \"1-1-1\",";
|
||||
ss << "\"practiceId\": \"2-2-2\",";
|
||||
ss << "\"practiceName\": \"practice1\",";
|
||||
ss << "\"files\": [ \"rules1\" ],";
|
||||
ss << "\"mode\": \"Prevent\"";
|
||||
ss << "}";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
SnortSignatures signatures;
|
||||
signatures.load(ar);
|
||||
setConfiguration(signatures, "IPSSnortSigs", "SnortProtections");
|
||||
}
|
||||
}
|
||||
|
||||
ParsedContextReply
|
||||
repondToContext(const string &buf_str, const string &name)
|
||||
{
|
||||
Buffer buf(buf_str);
|
||||
ScopedContext ctx;
|
||||
ctx.registerValue(name, buf);
|
||||
return entry.respond(ParsedContext(buf, name, 0));
|
||||
}
|
||||
|
||||
IPSEntry entry;
|
||||
TableOpaqueBase *ptr = &entry;
|
||||
|
||||
private:
|
||||
NiceMock<MockMainLoop> mock_mainloop;
|
||||
NiceMock<MockTimeGet> time;
|
||||
::Environment env;
|
||||
GenericRulebase generic_rulebase;
|
||||
ConfigComponent conf;
|
||||
KeywordComp keywords;
|
||||
AgentDetails details;
|
||||
NiceMock<MockLogging> logs;
|
||||
NiceMock<MockTable> table;
|
||||
MockAgg mock_agg;
|
||||
};
|
||||
|
||||
TEST_F(EntryTest, basic_inherited_functions)
|
||||
{
|
||||
EXPECT_EQ(IPSEntry::name(), "IPS");
|
||||
EXPECT_EQ(IPSEntry::currVer(), 0);
|
||||
EXPECT_EQ(IPSEntry::minVer(), 0);
|
||||
EXPECT_NE(IPSEntry::prototype(), nullptr);
|
||||
EXPECT_EQ(entry.getListenerName(), IPSEntry::name());
|
||||
|
||||
stringstream ss;
|
||||
{
|
||||
cereal::JSONOutputArchive ar(ss);
|
||||
entry.serialize(ar, 0);
|
||||
}
|
||||
EXPECT_EQ(ss.str(), "");
|
||||
|
||||
// Just make sure it doesn't crush
|
||||
entry.upon(ParsedContext(Buffer(), "Nothing", 0));
|
||||
}
|
||||
|
||||
TEST_F(EntryTest, check_listenning)
|
||||
{
|
||||
EXPECT_TRUE(Listener<ParsedContext>::empty());
|
||||
ptr->uponEnteringContext();
|
||||
EXPECT_FALSE(Listener<ParsedContext>::empty());
|
||||
ptr->uponLeavingContext();
|
||||
EXPECT_TRUE(Listener<ParsedContext>::empty());
|
||||
}
|
||||
|
||||
TEST_F(EntryTest, check_signature_invoking)
|
||||
{
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_REQUEST_BODY"), ParsedContextReply::ACCEPT);
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_RESPONSE_BODY"), ParsedContextReply::ACCEPT);
|
||||
|
||||
string signature =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
loadSignatures(signature);
|
||||
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_REQUEST_BODY"), ParsedContextReply::DROP);
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_RESPONSE_BODY"), ParsedContextReply::ACCEPT);
|
||||
}
|
||||
|
||||
TEST_F(EntryTest, check_snort_signature_invoking)
|
||||
{
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_REQUEST_BODY"), ParsedContextReply::ACCEPT);
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_RESPONSE_BODY"), ParsedContextReply::ACCEPT);
|
||||
|
||||
string signature =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"},"
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Bad sig\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: jjjj;\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
loadSnortSignatures(signature);
|
||||
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_REQUEST_BODY"), ParsedContextReply::DROP);
|
||||
EXPECT_EQ(repondToContext("ddd", "HTTP_RESPONSE_BODY"), ParsedContextReply::ACCEPT);
|
||||
}
|
||||
|
||||
TEST_F(EntryTest, flags_test)
|
||||
{
|
||||
EXPECT_FALSE(entry.isFlagSet("CONTEXT_A"));
|
||||
EXPECT_FALSE(entry.isFlagSet("CONTEXT_B"));
|
||||
entry.setFlag("CONTEXT_A");
|
||||
EXPECT_TRUE(entry.isFlagSet("CONTEXT_A"));
|
||||
EXPECT_FALSE(entry.isFlagSet("CONTEXT_B"));
|
||||
entry.unsetFlag("CONTEXT_A");
|
||||
EXPECT_FALSE(entry.isFlagSet("CONTEXT_A"));
|
||||
EXPECT_FALSE(entry.isFlagSet("CONTEXT_B"));
|
||||
}
|
||||
|
||||
TEST_F(EntryTest, get_buffer_test)
|
||||
{
|
||||
repondToContext("ddd", "HTTP_REQUEST_BODY");
|
||||
EXPECT_EQ(entry.getBuffer("HTTP_REQUEST_BODY"), Buffer("ddd"));
|
||||
EXPECT_EQ(entry.getBuffer("HTTP_REQUEST_HEADER"), Buffer());
|
||||
}
|
||||
|
||||
TEST_F(EntryTest, get_and_set_transaction_data)
|
||||
{
|
||||
EXPECT_FALSE(entry.getTransactionData(Buffer("transaction_key")).ok());
|
||||
entry.setTransactionData(Buffer("transaction_key"), Buffer("transaction_value"));
|
||||
ASSERT_TRUE(entry.getTransactionData(Buffer("transaction_key")).ok());
|
||||
EXPECT_EQ(entry.getTransactionData(Buffer("transaction_key")).unpack(), Buffer("transaction_value"));
|
||||
}
|
77
components/security_apps/ips/ips_ut/resource_ut.cc
Normal file
77
components/security_apps/ips/ips_ut/resource_ut.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "ips_signatures.h"
|
||||
#include "cptest.h"
|
||||
#include "environment.h"
|
||||
#include "config_component.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
static const string basic_resource =
|
||||
"{"
|
||||
"\"IPS\": {"
|
||||
"\"VersionId\": \"1234567\","
|
||||
"\"protections\": ["
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Null HTTP Encodings\","
|
||||
"\"severity\": \"Medium\","
|
||||
"\"confidenceLevel\": \"High\","
|
||||
"\"performanceImpact\": \"Medium\","
|
||||
"\"lastUpdate\": \"20130101\","
|
||||
"\"maintrainId\": \"8576967832\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": [],"
|
||||
"\"silent\": false"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"aaaa\","
|
||||
"\"keywords\": \"\","
|
||||
"\"context\": ["
|
||||
"\"HTTP_COMPLETE_URL_ENCODED\""
|
||||
"]"
|
||||
"}"
|
||||
"},"
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Null HTTP Encodings\","
|
||||
"\"severity\": \"Medium\","
|
||||
"\"confidenceLevel\": \"High\","
|
||||
"\"performanceImpact\": \"Medium\","
|
||||
"\"lastUpdate\": \"20130101\","
|
||||
"\"maintrainId\": \"8576967832\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": [],"
|
||||
"\"silent\": false"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"bbbbb\","
|
||||
"\"keywords\": \"\","
|
||||
"\"context\": ["
|
||||
"\"HTTP_COMPLETE_URL_ENCODED\""
|
||||
"]"
|
||||
"}"
|
||||
"}"
|
||||
"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
TEST(resources, basic_resource)
|
||||
{
|
||||
ConfigComponent conf;
|
||||
::Environment env;
|
||||
|
||||
conf.preload();
|
||||
|
||||
registerExpectedSetting<IPSSignaturesResource>("IPS", "protections");
|
||||
registerExpectedSetting<string>("IPS", "VersionId");
|
||||
stringstream resource;
|
||||
resource << basic_resource;
|
||||
Singleton::Consume<Config::I_Config>::from(conf)->loadConfiguration(resource);
|
||||
|
||||
auto loaded_resources = getSettingWithDefault(IPSSignaturesResource(), "IPS", "protections");
|
||||
EXPECT_EQ(loaded_resources.getSignatures().size(), 2);
|
||||
auto version = getSettingWithDefault<string>("", "IPS", "VersionId");
|
||||
EXPECT_EQ(version, "1234567");
|
||||
}
|
163
components/security_apps/ips/ips_ut/rule_selector_ut.cc
Normal file
163
components/security_apps/ips/ips_ut/rule_selector_ut.cc
Normal file
@@ -0,0 +1,163 @@
|
||||
#include <sstream>
|
||||
#include "ips_enums.h"
|
||||
#include "ips_basic_policy.h"
|
||||
#include "cptest.h"
|
||||
#include "config.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const RuleSelector &selector)
|
||||
{
|
||||
selector.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
class RuleSelectorTest : public Test
|
||||
{
|
||||
public:
|
||||
void
|
||||
load(const string &config)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << config;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
|
||||
ruleSelector.load(ar);
|
||||
}
|
||||
|
||||
string protection =
|
||||
"{"
|
||||
"\"defaultAction\": \"Prevent\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Detect\","
|
||||
"\"performanceImpact\": \"Medium or lower\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"confidenceLevel\": \"Medium\","
|
||||
"\"serverProtections\": false,"
|
||||
"\"clientProtections\": true,"
|
||||
"\"protectionsFromYear\": 2020,"
|
||||
"\"protectionTags\": ["
|
||||
"\"tag1\","
|
||||
"\"tag2\""
|
||||
"],"
|
||||
"\"protectionIds\": ["
|
||||
"\"id1\","
|
||||
"\"id2\""
|
||||
"]"
|
||||
"},"
|
||||
"{"
|
||||
"\"action\": \"Prevent\","
|
||||
"\"performanceImpact\": \"Very low\","
|
||||
"\"severityLevel\": \"Medium or above\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"serverProtections\": true,"
|
||||
"\"clientProtections\": false,"
|
||||
"\"protectionsFromYear\": 1999,"
|
||||
"\"protectionTags\": ["
|
||||
"\"tag11\","
|
||||
"\"tag22\""
|
||||
"],"
|
||||
"\"protectionIds\": ["
|
||||
"\"id11\","
|
||||
"\"id22\""
|
||||
"]"
|
||||
"}"
|
||||
"]"
|
||||
"}";
|
||||
|
||||
string protection2 =
|
||||
"{"
|
||||
"\"defaultAction\": \"Inactive\","
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Detect\","
|
||||
"\"performanceImpact\": \"Medium or lower\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"confidenceLevel\": \"Medium\""
|
||||
"},"
|
||||
"{"
|
||||
"\"action\": \"Prevent\""
|
||||
"}"
|
||||
"]"
|
||||
"}";
|
||||
|
||||
string protection3 =
|
||||
"{"
|
||||
"\"defaultAction\": \"Prevent\","
|
||||
"\"rules\": []"
|
||||
"}";
|
||||
|
||||
string protection4 =
|
||||
"{"
|
||||
"\"rules\": ["
|
||||
"{"
|
||||
"\"action\": \"Detect\","
|
||||
"\"performanceImpact\": \"Medium or lower\","
|
||||
"\"severityLevel\": \"Low or above\","
|
||||
"\"confidenceLevel\": \"Medium\""
|
||||
"},"
|
||||
"{"
|
||||
"\"action\": \"Prevent\""
|
||||
"}"
|
||||
"]"
|
||||
"}";
|
||||
|
||||
RuleSelector ruleSelector;
|
||||
};
|
||||
|
||||
TEST_F(RuleSelectorTest, read_rules)
|
||||
{
|
||||
load(protection);
|
||||
ostringstream stream;
|
||||
stream << ruleSelector;
|
||||
string str = stream.str();
|
||||
string result =
|
||||
"[Rule] action: 1 performanceImpact: 3 severityLevel: 1 confidenceLevel: 3 serverProtections: false"
|
||||
" clientProtections: true protectionsFromYear: 2020 protectionIds: id1, id2 protectionTags: tag1, tag2;"
|
||||
"[Rule] action: 0 performanceImpact: 0 severityLevel: 3 confidenceLevel: 1 serverProtections: true"
|
||||
" clientProtections: false protectionsFromYear: 1999 protectionIds: id11, id22 protectionTags: tag11, tag22;"
|
||||
"[Rule] action: 0";
|
||||
|
||||
EXPECT_EQ(result, str);
|
||||
}
|
||||
|
||||
TEST_F(RuleSelectorTest, read_semi_rules)
|
||||
{
|
||||
load(protection2);
|
||||
ostringstream stream;
|
||||
stream << ruleSelector;
|
||||
string str = stream.str();
|
||||
string result =
|
||||
"[Rule] action: 1 performanceImpact: 3 severityLevel: 1 confidenceLevel: 3;"
|
||||
"[Rule] action: 0;"
|
||||
"[Rule] action: 2";
|
||||
|
||||
EXPECT_EQ(result, str);
|
||||
}
|
||||
|
||||
TEST_F(RuleSelectorTest, read_empty_rules)
|
||||
{
|
||||
try
|
||||
{
|
||||
load(protection3);
|
||||
}
|
||||
catch(const Config::ConfigException &e)
|
||||
{
|
||||
EXPECT_EQ("rules array is empty", e.getError());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(RuleSelectorTest, read_no_default_action)
|
||||
{
|
||||
try
|
||||
{
|
||||
load(protection4);
|
||||
}
|
||||
catch(const cereal::Exception &e)
|
||||
{
|
||||
EXPECT_EQ("JSON Parsing failed - provided NVP (defaultAction) not found", string(e.what()));
|
||||
}
|
||||
}
|
661
components/security_apps/ips/ips_ut/signatures_ut.cc
Normal file
661
components/security_apps/ips/ips_ut/signatures_ut.cc
Normal file
@@ -0,0 +1,661 @@
|
||||
#include "ips_signatures.h"
|
||||
#include "ips_common_types.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include "cptest.h"
|
||||
|
||||
#include "keyword_comp.h"
|
||||
#include "environment.h"
|
||||
#include "agent_details.h"
|
||||
#include "mock/mock_logging.h"
|
||||
#include "time_proxy.h"
|
||||
#include "config.h"
|
||||
#include "config_component.h"
|
||||
#include "i_keywords_rule.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "generic_rulebase/generic_rulebase.h"
|
||||
#include "generic_rulebase/parameters_config.h"
|
||||
#include "generic_rulebase/generic_rulebase_context.h"
|
||||
#include "encryptor.h"
|
||||
#include "mock/mock_table.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace std;
|
||||
|
||||
MATCHER_P(IsLog, IteratableFields, "")
|
||||
{
|
||||
stringstream ss;
|
||||
{
|
||||
cereal::JSONOutputArchive ar(ss);
|
||||
ar(arg);
|
||||
}
|
||||
for (const auto &field : IteratableFields) {
|
||||
if (ss.str().find(field) == string::npos) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class MockAgg : Singleton::Provide<I_FirstTierAgg>::SelfInterface
|
||||
{
|
||||
shared_ptr<PMHook>
|
||||
getHook(const string &, const set<PMPattern> &pats) override
|
||||
{
|
||||
auto hook = make_shared<PMHook>();
|
||||
hook->prepare(pats);
|
||||
return hook;
|
||||
}
|
||||
};
|
||||
|
||||
class SignatureTest : public Test
|
||||
{
|
||||
public:
|
||||
SignatureTest()
|
||||
{
|
||||
generic_rulebase.preload();
|
||||
EXPECT_CALL(logs, getCurrentLogId()).Times(AnyNumber());
|
||||
ON_CALL(table, getState(_)).WillByDefault(Return(&ips_state));
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature1 << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
single_signature.load(ar);
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature3 << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
single_signature2.load(ar);
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature1 << ", " << signature2 << ", " << signature3 << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
multiple_signatures.load(ar);
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature_performance_very_low << ", " << signature_performance_low << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
performance_signatures1.load(ar);
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature_performance_medium_low << ", " << signature_performance_medium << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
performance_signatures2.load(ar);
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature_performance_medium_high << ", " << signature_performance_high << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
performance_signatures3.load(ar);
|
||||
}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << signature_high_confidance << ", " << signature_medium_confidance << "]";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
high_medium_confidance_signatures.load(ar);
|
||||
}
|
||||
}
|
||||
|
||||
~SignatureTest()
|
||||
{
|
||||
if (gen_ctx != nullptr) {
|
||||
gen_ctx->deactivate();
|
||||
gen_ctx.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
loadExceptions()
|
||||
{
|
||||
env.preload();
|
||||
env.init();
|
||||
|
||||
BasicRuleConfig::preload();
|
||||
registerExpectedConfiguration<ParameterException>("rulebase", "exception");
|
||||
|
||||
string test_config(
|
||||
"{"
|
||||
" \"rulebase\": {"
|
||||
" \"rulesConfig\": ["
|
||||
" {"
|
||||
" \"context\": \"All()\","
|
||||
" \"priority\": 1,"
|
||||
" \"ruleId\": \"5eaef0726765c30010bae8bb\","
|
||||
" \"ruleName\": \"Acme web API\","
|
||||
" \"assetId\": \"5e243effd858007660b758ad\","
|
||||
" \"assetName\": \"Acme Power API\","
|
||||
" \"parameters\": ["
|
||||
" {"
|
||||
" \"parameterId\": \"6c3867be-4da5-42c2-93dc-8f509a764003\","
|
||||
" \"parameterType\": \"exceptions\","
|
||||
" \"parameterName\": \"exception\""
|
||||
" }"
|
||||
" ],"
|
||||
" \"zoneId\": \"\","
|
||||
" \"zoneName\": \"\""
|
||||
" }"
|
||||
" ],"
|
||||
" \"exception\": ["
|
||||
" {"
|
||||
" \"context\": \"parameterId(6c3867be-4da5-42c2-93dc-8f509a764003)\","
|
||||
" \"match\": {"
|
||||
" \"type\": \"operator\","
|
||||
" \"op\": \"or\","
|
||||
" \"items\": [{"
|
||||
" \"type\": \"condition\","
|
||||
" \"op\": \"equals\","
|
||||
" \"key\": \"protectionName\","
|
||||
" \"value\": [\"Test1\"]"
|
||||
" }, {"
|
||||
" \"type\": \"condition\","
|
||||
" \"op\": \"equals\","
|
||||
" \"key\": \"protectionName\","
|
||||
" \"value\": [\"Test2\"]"
|
||||
" }, {"
|
||||
" \"type\": \"condition\","
|
||||
" \"op\": \"equals\","
|
||||
" \"key\": \"sourceIdentifier\","
|
||||
" \"value\": [\"1.1.1.1\"]"
|
||||
" }]"
|
||||
" },"
|
||||
" \"behavior\": {"
|
||||
" \"key\": \"action\","
|
||||
" \"value\": \"accept\""
|
||||
" }"
|
||||
" }"
|
||||
" ]"
|
||||
" }"
|
||||
"}"
|
||||
);
|
||||
|
||||
istringstream ss(test_config);
|
||||
auto i_config = Singleton::Consume<Config::I_Config>::from(config);
|
||||
i_config->loadConfiguration(ss);
|
||||
|
||||
gen_ctx = make_unique<GenericRulebaseContext>();
|
||||
gen_ctx->activate();
|
||||
}
|
||||
|
||||
void
|
||||
load(const IPSSignaturesResource &policy, const string &severity, const string &confidence)
|
||||
{
|
||||
setResource(policy, "IPS", "protections");
|
||||
stringstream ss;
|
||||
ss << "{";
|
||||
ss << "\"ruleName\": \"rule1\", \"assetName\": \"asset1\", \"practiceName\": \"practice1\",";
|
||||
ss << "\"assetId\": \"1-1-1\", \"practiceId\": \"2-2-2\",";
|
||||
ss << "\"defaultAction\" : " << "\"Detect\",";
|
||||
ss << "\"rules\": [";
|
||||
ss << "{";
|
||||
ss << "\"action\": \"Prevent\",";
|
||||
ss << "\"performanceImpact\": \"High or lower\",";
|
||||
ss << "\"severityLevel\": \"" << severity << "\",";
|
||||
ss << "\"confidenceLevel\": \"" << confidence << "\"";
|
||||
ss << "}";
|
||||
ss << "]";
|
||||
ss << "}";
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
sigs.load(ar);
|
||||
}
|
||||
|
||||
bool
|
||||
checkData(const string &data, const string &ctx_name = "HTTP_REQUEST_BODY")
|
||||
{
|
||||
ParsedContext body(data, ctx_name, 0);
|
||||
ScopedContext ctx;
|
||||
ctx.registerValue<string>(I_KeywordsRule::getKeywordsRuleTag(), ctx_name);
|
||||
ctx.registerValue(body.getName(), body.getBuffer());
|
||||
return sigs.isMatchedPrevent(body.getName(), body.getBuffer());
|
||||
}
|
||||
|
||||
template <typename ...Strings>
|
||||
void
|
||||
expectLog(const string &field, Strings ...more_fields)
|
||||
{
|
||||
vector<string> all_fields;
|
||||
all_fields.push_back(field);
|
||||
expectLog(all_fields, more_fields...);
|
||||
}
|
||||
|
||||
template <typename ...Strings>
|
||||
void
|
||||
expectLog(vector<string> all_fields, const string &field, Strings ...more_fields)
|
||||
{
|
||||
all_fields.push_back(field);
|
||||
expectLog(all_fields, more_fields...);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
expectLog(vector<string> all_fields)
|
||||
{
|
||||
EXPECT_CALL(logs, sendLog(IsLog(all_fields)));
|
||||
}
|
||||
|
||||
IPSSignatures sigs;
|
||||
IPSSignaturesResource single_signature;
|
||||
IPSSignaturesResource single_signature2;
|
||||
IPSSignaturesResource multiple_signatures;
|
||||
IPSSignaturesResource high_medium_confidance_signatures;
|
||||
IPSSignaturesResource performance_signatures1;
|
||||
IPSSignaturesResource performance_signatures2;
|
||||
IPSSignaturesResource performance_signatures3;
|
||||
NiceMock<MockTable> table;
|
||||
MockAgg mock_agg;
|
||||
|
||||
private:
|
||||
GenericRulebase generic_rulebase;
|
||||
unique_ptr<GenericRulebaseContext> gen_ctx;
|
||||
NiceMock<MockMainLoop> mock_mainloop;
|
||||
KeywordComp keywords;
|
||||
TimeProxyComponent time;
|
||||
::Environment env;
|
||||
ConfigComponent config;
|
||||
Encryptor encryptor;
|
||||
AgentDetails details;
|
||||
StrictMock<MockLogging> logs;
|
||||
IPSEntry ips_state;
|
||||
|
||||
string signature1 =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [\"Protection_Type_Scanning_Tool\"],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"fff\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
string signature2 =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test2\","
|
||||
"\"maintrainId\": \"102\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [\"Vul_Type_SQL_Injection\"],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"ddd\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
string signature3 =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test3\","
|
||||
"\"maintrainId\": \"102\","
|
||||
"\"severity\": \"High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [\"Protection_Type_Scanning_Tool\", \"Vul_Type_SQL_Injection\"],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"ggg\","
|
||||
"\"keywords\": \"\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_high_confidance =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test3\","
|
||||
"\"maintrainId\": \"103\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"High\","
|
||||
"\"performanceImpact\": \"Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"hhh\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_medium_confidance =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test4\","
|
||||
"\"maintrainId\": \"104\","
|
||||
"\"severity\": \"Low\","
|
||||
"\"confidenceLevel\": \"Medium\","
|
||||
"\"performanceImpact\": \"Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"mmm\","
|
||||
"\"keywords\": \"data: \\\"mmm\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_performance_very_low =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Very Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"aaa\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_performance_low =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"bbb\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_performance_medium_low =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium Low\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ccc\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_performance_medium =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"ddd\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_performance_medium_high =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"Medium High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"eee\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
string signature_performance_high =
|
||||
"{"
|
||||
"\"protectionMetadata\": {"
|
||||
"\"protectionName\": \"Test1\","
|
||||
"\"maintrainId\": \"101\","
|
||||
"\"severity\": \"Medium High\","
|
||||
"\"confidenceLevel\": \"Low\","
|
||||
"\"performanceImpact\": \"High\","
|
||||
"\"lastUpdate\": \"20210420\","
|
||||
"\"tags\": [],"
|
||||
"\"cveList\": []"
|
||||
"},"
|
||||
"\"detectionRules\": {"
|
||||
"\"type\": \"simple\","
|
||||
"\"SSM\": \"\","
|
||||
"\"keywords\": \"data: \\\"fff\\\";\","
|
||||
"\"context\": [\"HTTP_REQUEST_BODY\", \"HTTP_RESPONSE_BODY\"]"
|
||||
"}"
|
||||
"}";
|
||||
};
|
||||
|
||||
TEST_F(SignatureTest, basic_load_of_signatures)
|
||||
{
|
||||
EXPECT_TRUE(sigs.isEmpty());
|
||||
load(single_signature, "Low or above", "Low");
|
||||
EXPECT_FALSE(sigs.isEmpty());
|
||||
EXPECT_TRUE(sigs.isEmpty("NO_CONTEXT"));
|
||||
EXPECT_FALSE(sigs.isEmpty("HTTP_REQUEST_BODY"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, single_signature_matching_override)
|
||||
{
|
||||
load(single_signature, "Low or above", "Low");
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"", "\"eventSeverity\": \"High\"");
|
||||
|
||||
EXPECT_TRUE(checkData("fffddd"));
|
||||
|
||||
loadExceptions();
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"", "\"eventSeverity\": \"Info\"");
|
||||
|
||||
EXPECT_FALSE(checkData("fffddd"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, source_idetifier_exception)
|
||||
{
|
||||
load(single_signature2, "Low or above", "Low");
|
||||
|
||||
loadExceptions();
|
||||
|
||||
expectLog("\"protectionId\": \"Test3\"", "\"eventSeverity\": \"Critical\"");
|
||||
|
||||
EXPECT_TRUE(checkData("gggddd"));
|
||||
|
||||
ScopedContext ctx;
|
||||
ctx.registerValue<string>("sourceIdentifiers", "1.1.1.1");
|
||||
|
||||
expectLog("\"protectionId\": \"Test3\"", "\"eventSeverity\": \"Info\"");
|
||||
|
||||
EXPECT_FALSE(checkData("gggddd"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, single_signature_matching)
|
||||
{
|
||||
load(single_signature, "Low or above", "Low");
|
||||
|
||||
EXPECT_FALSE(checkData("ggg"));
|
||||
|
||||
EXPECT_FALSE(checkData("ddd"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"", "\"eventSeverity\": \"High\"");
|
||||
|
||||
EXPECT_TRUE(checkData("fffddd"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, context_signature_matching)
|
||||
{
|
||||
load(single_signature, "Low or above", "Low");
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"", "\"eventSeverity\": \"High\"");
|
||||
EXPECT_TRUE(checkData("fff", "HTTP_REQUEST_BODY"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"", "\"eventSeverity\": \"High\"");
|
||||
EXPECT_TRUE(checkData("fff", "HTTP_RESPONSE_BODY"));
|
||||
|
||||
EXPECT_FALSE(checkData("fff", "HTTP_COMPLETE_URL_DECODED"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, id_to_log_test)
|
||||
{
|
||||
load(single_signature, "Low or above", "Low");
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"");
|
||||
|
||||
EXPECT_TRUE(checkData("fffddd"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, multiple_signatures_matching)
|
||||
{
|
||||
load(multiple_signatures, "Low or above", "Low");
|
||||
EXPECT_FALSE(checkData("hhh"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test2\"", "\"eventSeverity\": \"High\"");
|
||||
EXPECT_TRUE(checkData("ddd"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test1\"", "\"eventSeverity\": \"High\"");
|
||||
EXPECT_TRUE(checkData("fff"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test3\"", "\"eventSeverity\": \"Critical\"");
|
||||
EXPECT_TRUE(checkData("ggg"));
|
||||
|
||||
// Only one signature is caught
|
||||
expectLog("\"protectionId\": \"Test2\"", "\"eventSeverity\": \"High\"");
|
||||
EXPECT_TRUE(checkData("fffdddggg"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, severity_to_log_test)
|
||||
{
|
||||
load(multiple_signatures, "Low or above", "Low");
|
||||
|
||||
expectLog("\"matchedSignatureSeverity\": \"Medium High\"");
|
||||
EXPECT_TRUE(checkData("fff"));
|
||||
|
||||
expectLog("\"matchedSignatureSeverity\": \"Low\"");
|
||||
EXPECT_TRUE(checkData("ddd"));
|
||||
|
||||
expectLog("\"matchedSignatureSeverity\": \"High\"");
|
||||
EXPECT_TRUE(checkData("ggg"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, incident_type)
|
||||
{
|
||||
load(multiple_signatures, "Low or above", "Low");
|
||||
|
||||
expectLog("\"waapIncidentType\": \"Scanning Tool\"");
|
||||
EXPECT_TRUE(checkData("fff"));
|
||||
|
||||
expectLog("\"waapIncidentType\": \"SQL Injection\"");
|
||||
EXPECT_TRUE(checkData("ddd"));
|
||||
|
||||
expectLog("\"waapIncidentType\": \"SQL Injection\"");
|
||||
EXPECT_TRUE(checkData("ggg"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, performance_to_log_very_low)
|
||||
{
|
||||
load(performance_signatures1, "Low or above", "Low");
|
||||
|
||||
EXPECT_FALSE(checkData("ggg"));
|
||||
|
||||
expectLog("\"matchedSignaturePerformance\": \"Very Low\"");
|
||||
|
||||
EXPECT_TRUE(checkData("aaa"));
|
||||
|
||||
expectLog("\"matchedSignaturePerformance\": \"Low\"");
|
||||
|
||||
EXPECT_TRUE(checkData("bbb"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, performance_to_log_medium_low)
|
||||
{
|
||||
load(performance_signatures2, "Low or above", "Low");
|
||||
|
||||
EXPECT_FALSE(checkData("ggg"));
|
||||
|
||||
expectLog("\"matchedSignaturePerformance\": \"Medium Low\"");
|
||||
|
||||
EXPECT_TRUE(checkData("ccc"));
|
||||
|
||||
expectLog("\"matchedSignaturePerformance\": \"Medium\"");
|
||||
|
||||
EXPECT_TRUE(checkData("ddd"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, performance_to_log_medium_high)
|
||||
{
|
||||
load(performance_signatures3, "Low or above", "Low");
|
||||
|
||||
EXPECT_FALSE(checkData("ggg"));
|
||||
|
||||
expectLog("\"matchedSignaturePerformance\": \"Medium High\"");
|
||||
|
||||
EXPECT_TRUE(checkData("eee"));
|
||||
|
||||
expectLog("\"matchedSignaturePerformance\": \"High\"");
|
||||
|
||||
EXPECT_TRUE(checkData("fff"));
|
||||
}
|
||||
|
||||
TEST_F(SignatureTest, high_confidance_signatures_matching)
|
||||
{
|
||||
load(high_medium_confidance_signatures, "Low or above", "High");
|
||||
EXPECT_FALSE(checkData("ggg"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test3\"", "\"matchedSignatureConfidence\": \"High\"");
|
||||
EXPECT_TRUE(checkData("hhh"));
|
||||
|
||||
expectLog("\"protectionId\": \"Test4\"", "\"matchedSignatureConfidence\": \"Medium\"");
|
||||
EXPECT_FALSE(checkData("mmm"));
|
||||
}
|
Reference in New Issue
Block a user