Mar 21st 2024 update

This commit is contained in:
Ned Wright
2024-03-21 15:31:38 +00:00
parent 0d22790ebe
commit c20fa9f966
100 changed files with 3851 additions and 453 deletions

View File

@@ -12,20 +12,34 @@
// limitations under the License.
#include "access_control_practice.h"
#include "new_practice.h"
using namespace std;
USE_DEBUG_FLAG(D_LOCAL_POLICY);
// LCOV_EXCL_START Reason: no test exist
static const map<string, string> valid_modes_to_key = {
static const set<string> valid_modes = {
"prevent",
"detect",
"inactive",
"prevent-learn",
"detect-learn",
"as-top-level",
"inherited"
};
static const unordered_map<string, string> valid_modes_to_key = {
{"prevent", "Active"},
{"prevent-learn", "Active"},
{"detect", "Detect"},
{"detect-learn", "Detect"},
{"inactive", "Inactive"}
};
static const set<string> valid_units = {"minute", "second"};
static const std::unordered_map<std::string, std::string> key_to_units_val = {
static const unordered_map<std::string, std::string> key_to_units_val = {
{ "second", "Second"},
{ "minute", "Minute"}
};
@@ -177,13 +191,10 @@ void
AccessControlRateLimit::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading Access control rate limit";
string in_mode;
parseAppsecJSONKey<string>("overrideMode", in_mode, archive_in, "detect");
if (valid_modes_to_key.find(in_mode) == valid_modes_to_key.end()) {
dbgWarning(D_LOCAL_POLICY) << "AppSec access control rate limit override mode invalid: " << in_mode;
throw PolicyGenException("AppSec access control rate limit override mode invalid: " + in_mode);
} else {
mode = valid_modes_to_key.at(in_mode);
parseMandatoryAppsecJSONKey<string>("overrideMode", mode, archive_in, "inactive");
if (valid_modes.find(mode) == valid_modes.end()) {
dbgWarning(D_LOCAL_POLICY) << "AppSec access control rate limit override mode invalid: " << mode;
throw PolicyGenException("AppSec access control rate limit override mode invalid: " + mode);
}
parseAppsecJSONKey<std::vector<AccessControlRateLimiteRules>>("rules", rules, archive_in);
}
@@ -205,9 +216,10 @@ AccessControlRateLimit::getRules() const
}
const string &
AccessControlRateLimit::getMode() const
AccessControlRateLimit::getMode(const std::string &default_mode) const
{
return mode;
const string &res = getModeWithDefault(mode, default_mode, valid_modes_to_key);
return res;
}
void
@@ -227,7 +239,7 @@ AccessControlPracticeSpec::setName(const string &_name)
}
const AccessControlRateLimit &
AccessControlPracticeSpec::geRateLimit() const
AccessControlPracticeSpec::getRateLimit() const
{
return rate_limit;
}

View File

@@ -133,7 +133,7 @@ AppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
parseAppsecJSONKey<AppSecWebAttackProtections>("protections", protections, archive_in);
parseAppsecJSONKey<string>("override-mode", mode, archive_in, "Unset");
parseAppsecJSONKey<string>("override-mode", mode, archive_in, "as-top-level");
if (valid_modes.count(mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode;
}
@@ -187,7 +187,7 @@ AppSecPracticeWebAttacks::getMinimumConfidence() const
const string &
AppSecPracticeWebAttacks::getMode(const string &default_mode) const
{
if (mode == "Unset" || (key_to_practices_val2.find(mode) == key_to_practices_val2.end())) {
if (isModeInherited(mode) || (key_to_practices_val2.find(mode) == key_to_practices_val2.end())) {
dbgError(D_LOCAL_POLICY) << "Couldn't find a value for key: " << mode << ". Returning " << default_mode;
return default_mode;
}
@@ -429,6 +429,9 @@ WebAppSection::WebAppSection(
context(_context),
web_attack_mitigation_severity(parsed_appsec_spec.getWebAttacks().getMinimumConfidence()),
web_attack_mitigation_mode(parsed_appsec_spec.getWebAttacks().getMode(default_mode)),
csrf_protection_mode("Disabled"),
open_redirect_mode("Disabled"),
error_disclosure_mode("Disabled"),
practice_advanced_config(parsed_appsec_spec),
anti_bots(parsed_appsec_spec.getAntiBot()),
trusted_sources({ parsed_trusted_sources })
@@ -451,6 +454,7 @@ WebAppSection::WebAppSection(
}
}
// Used for V1Beta2
WebAppSection::WebAppSection(
const string &_application_urls,
const string &_asset_id,
@@ -465,7 +469,8 @@ WebAppSection::WebAppSection(
const PracticeAdvancedConfig &_practice_advanced_config,
const AppsecPracticeAntiBotSection &_anti_bots,
const LogTriggerSection &parsed_log_trigger,
const AppSecTrustedSources &parsed_trusted_sources)
const AppSecTrustedSources &parsed_trusted_sources,
const NewAppSecWebAttackProtections &protections)
:
application_urls(_application_urls),
asset_id(_asset_id),
@@ -489,6 +494,10 @@ WebAppSection::WebAppSection(
web_attack_mitigation_severity == "medium" ? "high" :
"Error";
csrf_protection_mode = protections.getCsrfProtectionMode(_web_attack_mitigation_mode);
open_redirect_mode = protections.getOpenRedirectMode(_web_attack_mitigation_mode);
error_disclosure_mode = protections.getErrorDisclosureMode(_web_attack_mitigation_mode);
triggers.push_back(TriggersInWaapSection(parsed_log_trigger));
for (const SourcesIdentifiers &source_ident : parsed_trusted_sources.getSourcesIdentifiers()) {
overrides.push_back(AppSecOverride(source_ident));
@@ -510,9 +519,9 @@ WebAppSection::save(cereal::JSONOutputArchive &out_ar) const
cereal::make_nvp("webAttackMitigationAction", web_attack_mitigation_action),
cereal::make_nvp("webAttackMitigationMode", web_attack_mitigation_mode),
cereal::make_nvp("practiceAdvancedConfig", practice_advanced_config),
cereal::make_nvp("csrfProtection", disabled_str),
cereal::make_nvp("openRedirect", disabled_str),
cereal::make_nvp("errorDisclosure", disabled_str),
cereal::make_nvp("csrfProtection", csrf_protection_mode),
cereal::make_nvp("openRedirect", open_redirect_mode),
cereal::make_nvp("errorDisclosure", error_disclosure_mode),
cereal::make_nvp("practiceId", practice_id),
cereal::make_nvp("practiceName", practice_name),
cereal::make_nvp("assetId", asset_id),

View File

@@ -165,7 +165,7 @@ public:
void load(cereal::JSONInputArchive &archive_in);
const std::vector<AccessControlRateLimiteRules> & getRules() const;
const std::string & getMode() const;
const std::string & getMode(const std::string &default_mode = "inactive") const;
std::vector<RateLimitRulesSection> createRateLimitRulesSection(const RateLimitRulesTriggerSection &trigger) const;
private:
@@ -178,7 +178,7 @@ class AccessControlPracticeSpec
public:
void load(cereal::JSONInputArchive &archive_in);
const AccessControlRateLimit & geRateLimit() const;
const AccessControlRateLimit &getRateLimit() const;
const std::string & getAppSecClassName() const;
const std::string & getName() const;
void setName(const std::string &_name);

View File

@@ -278,6 +278,7 @@ public:
const std::vector<InnerException> &parsed_exceptions
);
// used for V1beta2
WebAppSection(
const std::string &_application_urls,
const std::string &_asset_id,
@@ -292,7 +293,8 @@ public:
const PracticeAdvancedConfig &_practice_advanced_config,
const AppsecPracticeAntiBotSection &_anti_bots,
const LogTriggerSection &parsed_log_trigger,
const AppSecTrustedSources &parsed_trusted_sources);
const AppSecTrustedSources &parsed_trusted_sources,
const NewAppSecWebAttackProtections &protections);
void save(cereal::JSONOutputArchive &out_ar) const;
@@ -310,6 +312,9 @@ private:
std::string web_attack_mitigation_action;
std::string web_attack_mitigation_severity;
std::string web_attack_mitigation_mode;
std::string csrf_protection_mode;
std::string open_redirect_mode;
std::string error_disclosure_mode;
bool web_attack_mitigation;
std::vector<TriggersInWaapSection> triggers;
PracticeAdvancedConfig practice_advanced_config;

View File

@@ -97,8 +97,7 @@ parseAppsecJSONKey(
value = default_value;
if (!mandatory) {
dbgDebug(D_LOCAL_POLICY)
<< "Could not parse the required key. Key: \""<< key_name
<< "\", Error: " << e.what();
<< "Could not parse a non-mandatory key: \""<< key_name << "\", Error: " << e.what();
} else {
throw PolicyGenException(
"Could not parse a mandatory key: \"" + key_name + "\", Error: " + std::string(e.what())

View File

@@ -24,6 +24,14 @@
#include "debug.h"
#include "local_policy_common.h"
bool isModeInherited(const std::string &mode);
const std::string &getModeWithDefault(
const std::string &mode,
const std::string &default_mode,
const std::unordered_map<std::string, std::string> &key_to_val
);
class IpsProtectionsRulesSection
{
public:
@@ -126,8 +134,8 @@ class NewIntrusionPrevention
public:
void load(cereal::JSONInputArchive &archive_in);
std::vector<IpsProtectionsRulesSection> createIpsRules() const;
const std::string & getMode() const;
std::vector<IpsProtectionsRulesSection> createIpsRules(const std::string &default_mode) const;
const std::string & getMode(const std::string &default_mode = "inactive") const;
private:
std::string override_mode;
@@ -273,7 +281,8 @@ public:
const std::string &asset_name,
const std::string &asset_id,
const std::string &practice_name,
const std::string &practice_id
const std::string &practice_id,
const std::string &default_mode
) const;
private:
@@ -486,7 +495,7 @@ public:
void load(cereal::JSONInputArchive &archive_in);
void addFile(const std::string &file_name);
const std::string & getOverrideMode() const;
const std::string & getOverrideMode(const std::string &default_mode = "inactive") const;
const std::vector<std::string> & getConfigMap() const;
const std::vector<std::string> & getFiles() const;
bool isTemporary() const;
@@ -530,10 +539,10 @@ class NewAppSecWebAttackProtections
public:
void load(cereal::JSONInputArchive &archive_in);
const std::string getCsrfProtectionMode() const;
const std::string & getErrorDisclosureMode() const;
const std::string & getCsrfProtectionMode(const std::string &default_mode = "inactive") const;
const std::string & getErrorDisclosureMode(const std::string &default_mode = "inactive") const;
const std::string & getOpenRedirectMode(const std::string &default_mode = "inactive") const;
bool getNonValidHttpMethods() const;
const std::string getOpenRedirectMode() const;
private:
std::string csrf_protection;
@@ -551,9 +560,9 @@ public:
int getMaxHeaderSizeBytes() const;
int getMaxObjectDepth() const;
int getMaxUrlSizeBytes() const;
const std::string & getMinimumConfidence() const;
const NewAppSecWebAttackProtections & getprotections() const;
const std::string & getMode(const std::string &default_mode = "Inactive") const;
const std::string & getMinimumConfidence(const std::string &default_mode = "inactive") const;
const NewAppSecWebAttackProtections & getProtections() const;
const std::string & getMode(const std::string &default_mode = "inactive") const;
private:
int max_body_size_kb;

View File

@@ -158,7 +158,8 @@ private:
const std::string &source_identifier,
const std::string & context,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
std::map<AnnotationTypes, std::string> &rule_annotations,
const std::string &default_mode
);
void createSnortProtecionsSection(const std::string &file_name, bool is_temporary);
@@ -172,7 +173,8 @@ private:
const std::string &practice_id,
const std::string &source_identifier,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
std::map<AnnotationTypes, std::string> &rule_annotations,
const std::string &default_mode
);
void
@@ -183,7 +185,8 @@ private:
const std::string &practice_name,
const std::string & context,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
std::map<AnnotationTypes, std::string> &rule_annotations,
const std::string &default_mode
);
void
@@ -192,6 +195,7 @@ private:
const std::string &url,
const std::string &uri,
const std::string &trigger_id,
const std::string &default_mode,
const V1beta2AppsecLinuxPolicy &policy,
std::map<AnnotationTypes, std::string> &rule_annotations
);

View File

@@ -414,7 +414,7 @@ K8sPolicyUtils::createAppsecPolicyK8sFromV1beta2Crds(
vector<AccessControlPracticeSpec> access_control_practices =
extractV1Beta2ElementsFromCluster<AccessControlPracticeSpec>(
"accesscontrolpractice",
"accesscontrolpractices",
policy_elements_names[AnnotationTypes::ACCESS_CONTROL_PRACTICE]
);
@@ -489,6 +489,8 @@ K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &i
!doesVersionExist(maybe_appsec_policy_spec.unpack().getMetaData().getAnnotations(), "v1beta1")
) {
try {
std::string v1beta1_error =
maybe_appsec_policy_spec.ok() ? "There is no v1beta1 policy" : maybe_appsec_policy_spec.getErr();
dbgWarning(D_LOCAL_POLICY
) << "Failed to retrieve Appsec policy with crds version: v1beta1, Trying version: v1beta2";
auto maybe_v1beta2_appsec_policy_spec = getObjectFromCluster<AppsecSpecParser<NewAppsecPolicySpec>>(
@@ -498,7 +500,7 @@ K8sPolicyUtils::createAppsecPolicyK8s(const string &policy_name, const string &i
dbgWarning(D_LOCAL_POLICY)
<< "Failed to retrieve AppSec policy. Error: " << maybe_v1beta2_appsec_policy_spec.getErr();
return std::make_tuple(
genError("Failed to retrieve AppSec v1beta1 policy. Error: " + maybe_appsec_policy_spec.getErr()),
genError("Failed to retrieve AppSec v1beta1 policy. Error: " + v1beta1_error),
genError(
"Failed to retrieve AppSec v1beta2 policy. Error: " + maybe_v1beta2_appsec_policy_spec.getErr()
)
@@ -584,7 +586,9 @@ K8sPolicyUtils::createAppsecPoliciesFromIngresses()
);
if (!std::get<0>(maybe_appsec_policy).ok() && !std::get<1>(maybe_appsec_policy).ok()) {
dbgWarning(D_LOCAL_POLICY)
<< "Failed to create appsec policy. Error: "
<< "Failed to create appsec policy. v1beta1 Error: "
<< std::get<0>(maybe_appsec_policy).getErr()
<< ". v1beta2 Error: "
<< std::get<1>(maybe_appsec_policy).getErr();
continue;
}

View File

@@ -99,7 +99,7 @@ V1beta2AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in)
archive_in
);
parseAppsecJSONKey<vector<NewAppsecLogTrigger>>("logTriggers", log_triggers, archive_in);
parseAppsecJSONKey<vector<NewAppSecCustomResponse>>("customResponse", custom_responses, archive_in);
parseAppsecJSONKey<vector<NewAppSecCustomResponse>>("customResponses", custom_responses, archive_in);
parseAppsecJSONKey<vector<NewAppsecException>>("exceptions", exceptions, archive_in);
parseAppsecJSONKey<vector<NewTrustedSourcesSpec>>("trustedSources", trusted_sources, archive_in);
parseAppsecJSONKey<vector<NewSourcesIdentifiers>>("sourcesIdentifiers", sources_identifiers, archive_in);

View File

@@ -44,7 +44,7 @@ void
NewAppsecException::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading New AppSec exception";
parseAppsecJSONKey<string>("name", name, archive_in, "exception");
parseAppsecJSONKey<string>("name", name, archive_in);
parseMandatoryAppsecJSONKey<string>("action", action, archive_in, "accept");
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
if (valid_actions.count(action) == 0) {

View File

@@ -21,8 +21,16 @@ USE_DEBUG_FLAG(D_LOCAL_POLICY);
static const set<string> performance_impacts = {"low", "medium", "high"};
static const set<string> severity_levels = {"low", "medium", "high", "critical"};
static const set<string> size_unit = {"bytes", "KB", "MB", "GB"};
static const set<string> confidences_actions = {"prevent", "detect", "inactive"};
static const set<string> valid_modes = {"prevent", "detect", "inactive", "prevent-learn", "detect-learn"};
static const set<string> confidences_actions = {"prevent", "detect", "inactive", "as-top-level", "inherited"};
static const set<string> valid_modes = {
"prevent",
"detect",
"inactive",
"prevent-learn",
"detect-learn",
"as-top-level",
"inherited"
};
static const set<string> valid_confidences = {"medium", "high", "critical"};
static const std::unordered_map<std::string, std::string> key_to_performance_impact_val = {
{ "low", "Low or lower"},
@@ -48,6 +56,30 @@ static const std::unordered_map<std::string, uint64_t> unit_to_int = {
{ "MB", 1048576},
{ "GB", 1073741824}
};
static const std::string TRANSPARENT_MODE = "Transparent";
bool
isModeInherited(const string &mode)
{
return mode == "as-top-level" || mode == "inherited";
}
const std::string &
getModeWithDefault(
const std::string &mode,
const std::string &default_mode,
const std::unordered_map<std::string, std::string> &key_to_val)
{
if (isModeInherited(mode) && (key_to_val.find(default_mode) != key_to_val.end())) {
dbgError(D_LOCAL_POLICY) << "Setting to top-level mode: " << default_mode;
return key_to_val.at(default_mode);
}
else if (key_to_val.find(mode) == key_to_val.end()) {
dbgError(D_LOCAL_POLICY) << "Given mode: " << mode << " or top-level: " << default_mode << " is invalid.";
return key_to_val.at("inactive");
}
return key_to_val.at(mode);
}
void
NewAppSecWebBotsURI::load(cereal::JSONInputArchive &archive_in)
@@ -84,7 +116,7 @@ NewAppSecPracticeAntiBot::load(cereal::JSONInputArchive &archive_in)
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Web Bots";
parseAppsecJSONKey<vector<NewAppSecWebBotsURI>>("injectedUris", injected_uris, archive_in);
parseAppsecJSONKey<vector<NewAppSecWebBotsURI>>("validatedUris", validated_uris, archive_in);
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "Inactive");
parseMandatoryAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
if (valid_modes.count(override_mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec Web Bots override mode invalid: " << override_mode;
}
@@ -110,26 +142,33 @@ NewAppSecWebAttackProtections::load(cereal::JSONInputArchive &archive_in)
parseAppsecJSONKey<string>("csrfProtection", csrf_protection, archive_in, "inactive");
parseAppsecJSONKey<string>("errorDisclosure", error_disclosure, archive_in, "inactive");
parseAppsecJSONKey<string>("openRedirect", open_redirect, archive_in, "inactive");
if (valid_modes.count(csrf_protection) == 0 ||
valid_modes.count(error_disclosure) == 0 ||
valid_modes.count(open_redirect) == 0) {
string error_msg = "AppSec Attack Protections mode invalid. csrf_protection: " + csrf_protection +
" error_disclosure: " + error_disclosure + " open_redirect: " + open_redirect;
dbgWarning(D_LOCAL_POLICY) << error_msg;
throw PolicyGenException(error_msg);
}
parseAppsecJSONKey<bool>("nonValidHttpMethods", non_valid_http_methods, archive_in, false);
}
const string
NewAppSecWebAttackProtections::getCsrfProtectionMode() const
const string &
NewAppSecWebAttackProtections::getCsrfProtectionMode(const string &default_mode) const
{
if (key_to_practices_val.find(csrf_protection) == key_to_practices_val.end()) {
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< csrf_protection
<< ". Setting CSRF protection to Inactive";
return "Inactive";
}
return key_to_practices_val.at(csrf_protection);
return getModeWithDefault(csrf_protection, default_mode, key_to_practices_val2);
}
const string &
NewAppSecWebAttackProtections::getErrorDisclosureMode() const
NewAppSecWebAttackProtections::getErrorDisclosureMode(const string &default_mode) const
{
return error_disclosure;
return getModeWithDefault(error_disclosure, default_mode, key_to_practices_val2);
}
const string &
NewAppSecWebAttackProtections::getOpenRedirectMode(const string &default_mode) const
{
return getModeWithDefault(open_redirect, default_mode, key_to_practices_val2);
}
bool
@@ -138,40 +177,24 @@ NewAppSecWebAttackProtections::getNonValidHttpMethods() const
return non_valid_http_methods;
}
const string
NewAppSecWebAttackProtections::getOpenRedirectMode() const
{
if (key_to_practices_val.find(open_redirect) == key_to_practices_val.end()) {
dbgError(D_LOCAL_POLICY)
<< "Failed to find a value for "
<< open_redirect
<< ". Setting Open Redirect mode to Inactive";
return "Inactive";
}
return key_to_practices_val.at(open_redirect);
}
void
NewAppSecPracticeWebAttacks::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice web attacks spec";
parseAppsecJSONKey<NewAppSecWebAttackProtections>("protections", protections, archive_in);
parseAppsecJSONKey<string>("overrideMode", mode, archive_in, "Unset");
parseMandatoryAppsecJSONKey<string>("overrideMode", mode, archive_in, "inactive");
if (valid_modes.count(mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec practice override mode invalid: " << mode;
}
if (getMode() == "Prevent") {
parseMandatoryAppsecJSONKey<string>("minimumConfidence", minimum_confidence, archive_in, "critical");
if (valid_confidences.count(minimum_confidence) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec practice override minimum confidence invalid: "
<< minimum_confidence;
throw PolicyGenException("AppSec practice override minimum confidence invalid: " + minimum_confidence);
}
} else {
minimum_confidence = "Transparent";
parseAppsecJSONKey<string>("minimumConfidence", minimum_confidence, archive_in, "critical");
if (valid_confidences.count(minimum_confidence) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec practice override minimum confidence invalid: "
<< minimum_confidence;
throw PolicyGenException("AppSec practice override minimum confidence invalid: " + minimum_confidence);
}
parseAppsecJSONKey<int>("maxBodySizeKb", max_body_size_kb, archive_in, 1000000);
parseAppsecJSONKey<int>("maxHeaderSizeBytes", max_header_size_bytes, archive_in, 102400);
parseAppsecJSONKey<int>("maxObjectDepth", max_object_depth, archive_in, 40);
@@ -203,19 +226,25 @@ NewAppSecPracticeWebAttacks::getMaxUrlSizeBytes() const
}
const string &
NewAppSecPracticeWebAttacks::getMinimumConfidence() const
NewAppSecPracticeWebAttacks::getMinimumConfidence(const string &default_mode) const
{
if (getMode(default_mode) != "Prevent") {
return TRANSPARENT_MODE;
}
return minimum_confidence;
}
const string &
NewAppSecPracticeWebAttacks::getMode(const string &default_mode) const
{
if (mode == "Unset" || (key_to_practices_val2.find(mode) == key_to_practices_val2.end())) {
dbgError(D_LOCAL_POLICY) << "Couldn't find a value for key: " << mode << ". Returning " << default_mode;
return default_mode;
}
return key_to_practices_val2.at(mode);
const string &res = getModeWithDefault(mode, default_mode, key_to_practices_val);
return res;
}
const NewAppSecWebAttackProtections &
NewAppSecPracticeWebAttacks::getProtections() const
{
return protections;
}
SnortProtectionsSection::SnortProtectionsSection(
@@ -244,7 +273,7 @@ SnortProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
{
out_ar(
cereal::make_nvp("context", context),
cereal::make_nvp("mode", key_to_mode_val.at(mode)),
cereal::make_nvp("mode", mode),
cereal::make_nvp("files", files),
cereal::make_nvp("assetName", asset_name),
cereal::make_nvp("assetId", asset_id),
@@ -440,8 +469,8 @@ void
NewSnortSignaturesAndOpenSchemaAPI::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Snort Signatures practice";
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
parseMandatoryAppsecJSONKey<vector<string>>("configmap", config_map, archive_in);
parseMandatoryAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
parseAppsecJSONKey<vector<string>>("configmap", config_map, archive_in);
parseAppsecJSONKey<vector<string>>("files", files, archive_in);
is_temporary = false;
if (valid_modes.count(override_mode) == 0) {
@@ -457,9 +486,10 @@ NewSnortSignaturesAndOpenSchemaAPI::addFile(const string &file_name)
}
const string &
NewSnortSignaturesAndOpenSchemaAPI::getOverrideMode() const
NewSnortSignaturesAndOpenSchemaAPI::getOverrideMode(const string &default_mode) const
{
return override_mode;
const string &res = getModeWithDefault(override_mode, default_mode, key_to_practices_val);
return res;
}
const vector<string> &
@@ -491,7 +521,7 @@ IpsProtectionsRulesSection::save(cereal::JSONOutputArchive &out_ar) const
{
vector<string> protections;
out_ar(
cereal::make_nvp("action", key_to_mode_val.at(action)),
cereal::make_nvp("action", action),
cereal::make_nvp("confidenceLevel", confidence_level),
cereal::make_nvp("clientProtections", true),
cereal::make_nvp("serverProtections", true),
@@ -541,7 +571,7 @@ IpsProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
cereal::make_nvp("practiceName", practice_name),
cereal::make_nvp("practiceId", practice_id),
cereal::make_nvp("sourceIdentifier", source_identifier),
cereal::make_nvp("defaultAction", key_to_mode_val.at(mode)),
cereal::make_nvp("defaultAction", mode),
cereal::make_nvp("rules", rules)
);
}
@@ -566,7 +596,7 @@ void
NewIntrusionPrevention::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec Intrusion Prevention practice";
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
parseMandatoryAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
if (valid_modes.count(override_mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec Intrusion Prevention override mode invalid: " << override_mode;
throw PolicyGenException("AppSec Intrusion Prevention override mode invalid: " + override_mode);
@@ -580,13 +610,13 @@ NewIntrusionPrevention::load(cereal::JSONInputArchive &archive_in)
"AppSec Intrusion Prevention max performance impact invalid: " + max_performance_impact
);
}
parseAppsecJSONKey<string>("minSeverityLevel", min_severity_level, archive_in, "low");
parseAppsecJSONKey<string>("minSeverityLevel", min_severity_level, archive_in, "medium");
if (severity_levels.count(min_severity_level) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention min severity level invalid: "
<< min_severity_level;
}
parseAppsecJSONKey<string>("highConfidenceEventAction", high_confidence_event_action, archive_in, "prevent");
parseAppsecJSONKey<string>("highConfidenceEventAction", high_confidence_event_action, archive_in, "inherited");
if (confidences_actions.count(high_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention high confidence event invalid: "
@@ -595,7 +625,9 @@ NewIntrusionPrevention::load(cereal::JSONInputArchive &archive_in)
"AppSec Intrusion Prevention high confidence event invalid: " + high_confidence_event_action
);
}
parseAppsecJSONKey<string>("mediumConfidenceEventAction", medium_confidence_event_action, archive_in, "prevent");
parseAppsecJSONKey<string>(
"mediumConfidenceEventAction", medium_confidence_event_action, archive_in, "inherited"
);
if (confidences_actions.count(medium_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec Intrusion Prevention medium confidence event invalid: "
@@ -613,16 +645,16 @@ NewIntrusionPrevention::load(cereal::JSONInputArchive &archive_in)
"AppSec Intrusion Prevention low confidence event action invalid: " + low_confidence_event_action
);
}
parseAppsecJSONKey<int>("minCveYear", min_cve_Year, archive_in);
parseAppsecJSONKey<int>("minCveYear", min_cve_Year, archive_in, 2016);
}
vector<IpsProtectionsRulesSection>
NewIntrusionPrevention::createIpsRules() const
NewIntrusionPrevention::createIpsRules(const string &default_mode) const
{
vector<IpsProtectionsRulesSection> ips_rules;
IpsProtectionsRulesSection high_rule(
min_cve_Year,
high_confidence_event_action,
getModeWithDefault(high_confidence_event_action, default_mode, key_to_practices_val),
string("High"),
max_performance_impact,
string(""),
@@ -632,7 +664,7 @@ NewIntrusionPrevention::createIpsRules() const
IpsProtectionsRulesSection med_rule(
min_cve_Year,
medium_confidence_event_action,
getModeWithDefault(medium_confidence_event_action, default_mode, key_to_practices_val),
string("Medium"),
max_performance_impact,
string(""),
@@ -642,7 +674,7 @@ NewIntrusionPrevention::createIpsRules() const
IpsProtectionsRulesSection low_rule(
min_cve_Year,
low_confidence_event_action,
getModeWithDefault(low_confidence_event_action, default_mode, key_to_practices_val),
string("Low"),
max_performance_impact,
string(""),
@@ -654,9 +686,10 @@ NewIntrusionPrevention::createIpsRules() const
}
const std::string &
NewIntrusionPrevention::getMode() const
NewIntrusionPrevention::getMode(const std::string &default_mode) const
{
return override_mode;
const string &res = getModeWithDefault(override_mode, default_mode, key_to_practices_val);
return res;
}
FileSecurityProtectionsSection::FileSecurityProtectionsSection(
@@ -711,20 +744,20 @@ FileSecurityProtectionsSection::save(cereal::JSONOutputArchive &out_ar) const
cereal::make_nvp("assetId", asset_id),
cereal::make_nvp("practiceName", practice_name),
cereal::make_nvp("practiceId", practice_id),
cereal::make_nvp("action", key_to_mode_val.at(action)),
cereal::make_nvp("filesWithoutNameAction", key_to_mode_val.at(files_without_name_action)),
cereal::make_nvp("action", action),
cereal::make_nvp("filesWithoutNameAction", files_without_name_action),
cereal::make_nvp("allowFilesWithoutName", allow_files_without_name),
cereal::make_nvp("highConfidence", key_to_mode_val.at(high_confidence_action)),
cereal::make_nvp("mediumConfidence", key_to_mode_val.at(medium_confidence_action)),
cereal::make_nvp("lowConfidence", key_to_mode_val.at(low_confidence_action)),
cereal::make_nvp("highConfidence", high_confidence_action),
cereal::make_nvp("mediumConfidence", medium_confidence_action),
cereal::make_nvp("lowConfidence", low_confidence_action),
cereal::make_nvp("severityLevel", key_to_severity_level_val.at(severity_level)),
cereal::make_nvp("fileSizeLimitAction", key_to_mode_val.at(file_size_limit_action)),
cereal::make_nvp("fileSizeLimitAction", file_size_limit_action),
cereal::make_nvp("fileSizeLimit", file_size_limit),
cereal::make_nvp("requiredFileSizeLimit", required_file_size_limit),
cereal::make_nvp("requiredArchiveExtraction", required_archive_extraction),
cereal::make_nvp("archiveFileSizeLimit", archive_file_size_limit),
cereal::make_nvp("MultiLevelArchiveAction", key_to_mode_val.at(multi_level_archive_action)),
cereal::make_nvp("UnopenedArchiveAction", key_to_mode_val.at(unopened_archive_action))
cereal::make_nvp("MultiLevelArchiveAction", multi_level_archive_action),
cereal::make_nvp("UnopenedArchiveAction", unopened_archive_action)
);
}
@@ -748,7 +781,7 @@ void
NewFileSecurityArchiveInspection::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security Archive Inspection practice";
parseAppsecJSONKey<bool>("extractArchiveFiles", extract_archive_files, archive_in, true);
parseAppsecJSONKey<bool>("extractArchiveFiles", extract_archive_files, archive_in, false);
parseAppsecJSONKey<uint64_t>("scanMaxFileSize", scan_max_file_size, archive_in, 10);
parseAppsecJSONKey<string>("scanMaxFileSizeUnit", scan_max_file_size_unit, archive_in, "MB");
if (size_unit.count(scan_max_file_size_unit) == 0) {
@@ -763,7 +796,7 @@ NewFileSecurityArchiveInspection::load(cereal::JSONInputArchive &archive_in)
"archivedFilesWithinArchivedFiles",
archived_files_within_archived_files,
archive_in,
"prevent");
"inherited");
if (confidences_actions.count(archived_files_within_archived_files) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection archived files within archived files invalid: "
@@ -777,7 +810,7 @@ NewFileSecurityArchiveInspection::load(cereal::JSONInputArchive &archive_in)
"archivedFilesWhereContentExtractionFailed",
archived_files_where_content_extraction_failed,
archive_in,
"prevent");
"inherited");
if (confidences_actions.count(archived_files_where_content_extraction_failed) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection archived files within archived file invalid: "
@@ -834,7 +867,7 @@ NewFileSecurityLargeFileInspection::load(cereal::JSONInputArchive &archive_in)
"filesExceedingSizeLimitAction",
files_exceeding_size_limit_action,
archive_in,
"prevent");
"inherited");
if (confidences_actions.count(files_exceeding_size_limit_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security Archive Inspection archived files within archived files invalid: "
@@ -869,18 +902,18 @@ void
NewFileSecurity::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security practice";
parseAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
parseMandatoryAppsecJSONKey<string>("overrideMode", override_mode, archive_in, "inactive");
if (valid_modes.count(override_mode) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec File Security override mode invalid: " << override_mode;
throw PolicyGenException("AppSec File Security override mode invalid: " + override_mode);
}
parseMandatoryAppsecJSONKey<string>("minSeverityLevel", min_severity_level, archive_in, "low");
parseAppsecJSONKey<string>("minSeverityLevel", min_severity_level, archive_in, "medium");
if (severity_levels.count(min_severity_level) == 0) {
dbgWarning(D_LOCAL_POLICY) << "AppSec File Security min severity level invalid: " << min_severity_level;
min_severity_level = "low";
}
parseMandatoryAppsecJSONKey<string>(
"highConfidenceEventAction", high_confidence_event_action, archive_in, "inactive"
parseAppsecJSONKey<string>(
"highConfidenceEventAction", high_confidence_event_action, archive_in, "inherited"
);
if (confidences_actions.count(high_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
@@ -888,8 +921,8 @@ NewFileSecurity::load(cereal::JSONInputArchive &archive_in)
<< high_confidence_event_action;
high_confidence_event_action = "inactive";
}
parseMandatoryAppsecJSONKey<string>(
"mediumConfidenceEventAction", medium_confidence_event_action, archive_in, "inactive"
parseAppsecJSONKey<string>(
"mediumConfidenceEventAction", medium_confidence_event_action, archive_in, "inherited"
);
if (confidences_actions.count(medium_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
@@ -897,8 +930,8 @@ NewFileSecurity::load(cereal::JSONInputArchive &archive_in)
<< medium_confidence_event_action;
medium_confidence_event_action = "inactive";
}
parseMandatoryAppsecJSONKey<string>(
"lowConfidenceEventAction", low_confidence_event_action, archive_in, "inactive"
parseAppsecJSONKey<string>(
"lowConfidenceEventAction", low_confidence_event_action, archive_in, "detect"
);
if (confidences_actions.count(low_confidence_event_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
@@ -906,7 +939,7 @@ NewFileSecurity::load(cereal::JSONInputArchive &archive_in)
<< low_confidence_event_action;
low_confidence_event_action = "inactive";
}
parseMandatoryAppsecJSONKey<string>("unnamedFilesAction", unnamed_files_action, archive_in, "inactive");
parseAppsecJSONKey<string>("unnamedFilesAction", unnamed_files_action, archive_in, "inherited");
if (confidences_actions.count(unnamed_files_action) == 0) {
dbgWarning(D_LOCAL_POLICY)
<< "AppSec File Security low unnamed files action invalid: "
@@ -914,10 +947,8 @@ NewFileSecurity::load(cereal::JSONInputArchive &archive_in)
unnamed_files_action = "inactive";
}
parseAppsecJSONKey<bool>("threatEmulationEnabled", threat_emulation_enabled, archive_in);
parseMandatoryAppsecJSONKey<NewFileSecurityArchiveInspection>("archiveInspection", archive_inspection, archive_in);
parseMandatoryAppsecJSONKey<NewFileSecurityLargeFileInspection>(
"largeFileInspection", large_file_inspection, archive_in
);
parseAppsecJSONKey<NewFileSecurityArchiveInspection>("archiveInspection", archive_inspection, archive_in);
parseAppsecJSONKey<NewFileSecurityLargeFileInspection>("largeFileInspection", large_file_inspection, archive_in);
}
const string &
@@ -944,28 +975,37 @@ NewFileSecurity::createFileSecurityProtectionsSection(
const string &asset_name,
const string &asset_id,
const string &practice_name,
const string &practice_id) const
const string &practice_id,
const string &default_mode) const
{
string practice_action = (isModeInherited(override_mode) ? default_mode : override_mode);
const string &unnamed_files_action_val =
getModeWithDefault(unnamed_files_action, practice_action, key_to_mode_val);
const string &large_file_action_val = getModeWithDefault(
getLargeFileInspection().getFileSizeLimitAction(),
practice_action,
key_to_mode_val
);
return FileSecurityProtectionsSection(
getLargeFileInspection().getFileSizeLimit(),
getArchiveInspection().getArchiveFileSizeLimit(),
unnamed_files_action == "prevent" ? true : false,
getLargeFileInspection().getFileSizeLimitAction() == "prevent" ? true : false,
unnamed_files_action_val == "Prevent" ? true : false,
large_file_action_val == "Prevent" ? true : false,
getArchiveInspection().getrequiredArchiveExtraction(),
context,
asset_name,
asset_id,
practice_name,
practice_id,
override_mode,
unnamed_files_action,
high_confidence_event_action,
medium_confidence_event_action,
low_confidence_event_action,
getModeWithDefault(override_mode, practice_action, key_to_mode_val),
unnamed_files_action_val,
getModeWithDefault(high_confidence_event_action, practice_action, key_to_mode_val),
getModeWithDefault(medium_confidence_event_action, practice_action, key_to_mode_val),
getModeWithDefault(low_confidence_event_action, practice_action, key_to_mode_val),
min_severity_level,
getLargeFileInspection().getFileSizeLimitAction(),
getArchiveInspection().getMultiLevelArchiveAction(),
getArchiveInspection().getUnopenedArchiveAction()
large_file_action_val,
getModeWithDefault(getArchiveInspection().getMultiLevelArchiveAction(), practice_action, key_to_mode_val),
getModeWithDefault(getArchiveInspection().getUnopenedArchiveAction(), practice_action, key_to_mode_val)
);
}
@@ -974,14 +1014,14 @@ NewAppSecPracticeSpec::load(cereal::JSONInputArchive &archive_in)
{
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec practice spec";
parseAppsecJSONKey<NewSnortSignaturesAndOpenSchemaAPI>(
"openapi-schema-validation",
"schemaValidation",
openapi_schema_validation,
archive_in
);
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
parseAppsecJSONKey<NewFileSecurity>("fileSecurity", file_security, archive_in);
parseAppsecJSONKey<NewIntrusionPrevention>("intrusionPrevention", intrusion_prevention, archive_in);
parseAppsecJSONKey<NewSnortSignaturesAndOpenSchemaAPI>("snortSignatures", snort_signatures, archive_in);
parseMandatoryAppsecJSONKey<NewFileSecurity>("fileSecurity", file_security, archive_in);
parseMandatoryAppsecJSONKey<NewIntrusionPrevention>("intrusionPrevention", intrusion_prevention, archive_in);
parseMandatoryAppsecJSONKey<NewSnortSignaturesAndOpenSchemaAPI>("snortSignatures", snort_signatures, archive_in);
parseMandatoryAppsecJSONKey<NewAppSecPracticeWebAttacks>("webAttacks", web_attacks, archive_in);
parseAppsecJSONKey<NewAppSecPracticeAntiBot>("antiBot", anti_bot, archive_in);
parseAppsecJSONKey<string>("name", practice_name, archive_in);

View File

@@ -996,13 +996,15 @@ PolicyMakerUtils::createIpsSections(
const string &source_identifier,
const string & context,
const V1beta2AppsecLinuxPolicy &policy,
map<AnnotationTypes, string> &rule_annotations)
map<AnnotationTypes, string> &rule_annotations,
const string &default_mode)
{
auto apssec_practice = getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
rule_annotations[AnnotationTypes::PRACTICE],
policy);
if (apssec_practice.getIntrusionPrevention().getMode().empty()) return;
const string &override_mode = apssec_practice.getIntrusionPrevention().getMode(default_mode);
if (override_mode == "Inactive" || override_mode == "Disabled") return;
IpsProtectionsSection ips_section = IpsProtectionsSection(
context,
@@ -1011,8 +1013,8 @@ PolicyMakerUtils::createIpsSections(
practice_name,
practice_id,
source_identifier,
apssec_practice.getIntrusionPrevention().getMode(),
apssec_practice.getIntrusionPrevention().createIpsRules()
override_mode,
apssec_practice.getIntrusionPrevention().createIpsRules(override_mode)
);
ips[asset_name] = ips_section;
@@ -1068,13 +1070,16 @@ PolicyMakerUtils::createSnortSections(
const string &practice_id,
const string &source_identifier,
const V1beta2AppsecLinuxPolicy &policy,
map<AnnotationTypes, string> &rule_annotations)
map<AnnotationTypes, string> &rule_annotations,
const string &default_mode)
{
auto apssec_practice = getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
rule_annotations[AnnotationTypes::PRACTICE],
policy);
if (apssec_practice.getSnortSignatures().getOverrideMode() == "inactive" ||
const string &override_mode = apssec_practice.getSnortSignatures().getOverrideMode(default_mode);
if (override_mode == "Inactive" ||
override_mode == "Disabled" ||
apssec_practice.getSnortSignatures().getFiles().size() == 0) {
return;
}
@@ -1094,7 +1099,7 @@ PolicyMakerUtils::createSnortSections(
practice_name,
practice_id,
source_identifier,
apssec_practice.getSnortSignatures().getOverrideMode(),
override_mode,
apssec_practice.getSnortSignatures().getFiles()
);
@@ -1109,7 +1114,8 @@ PolicyMakerUtils::createFileSecuritySections(
const string &practice_name,
const string &context,
const V1beta2AppsecLinuxPolicy &policy,
map<AnnotationTypes, string> &rule_annotations)
map<AnnotationTypes, string> &rule_annotations,
const string &default_mode)
{
auto apssec_practice = getAppsecPracticeSpec<V1beta2AppsecLinuxPolicy, NewAppSecPracticeSpec>(
rule_annotations[AnnotationTypes::PRACTICE],
@@ -1122,7 +1128,8 @@ PolicyMakerUtils::createFileSecuritySections(
asset_name,
asset_id,
practice_name,
practice_id
practice_id,
default_mode
);
file_security[asset_name] = file_security_section;
@@ -1134,6 +1141,7 @@ PolicyMakerUtils::createRateLimitSection(
const string &url,
const string &uri,
const string &trigger_id,
const std::string &default_mode,
const V1beta2AppsecLinuxPolicy &policy,
map<AnnotationTypes, string> &rule_annotations)
{
@@ -1157,13 +1165,13 @@ PolicyMakerUtils::createRateLimitSection(
trigger = RateLimitRulesTriggerSection(trigger_id, trigger_name, "Trigger");
}
auto rules = access_control_practice.geRateLimit().createRateLimitRulesSection(trigger);
auto rules = access_control_practice.getRateLimit().createRateLimitRulesSection(trigger);
rate_limit[rule_annotations[AnnotationTypes::ACCESS_CONTROL_PRACTICE]] = RateLimitSection(
asset_name,
url,
uri,
access_control_practice.geRateLimit().getMode(),
access_control_practice.getRateLimit().getMode(default_mode),
practice_id,
rule_annotations[AnnotationTypes::ACCESS_CONTROL_PRACTICE],
rules
@@ -1198,12 +1206,13 @@ PolicyMakerUtils::createWebAppSection(
practice_id,
rule_annotations[AnnotationTypes::PRACTICE],
rule_config.getContext(),
apssec_practice.getWebAttacks().getMinimumConfidence(),
apssec_practice.getWebAttacks().getMinimumConfidence(default_mode),
apssec_practice.getWebAttacks().getMode(default_mode),
practice_advance_config,
apssec_practice.getAntiBot(),
log_triggers[rule_annotations[AnnotationTypes::TRIGGER]],
trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]]
trusted_sources[rule_annotations[AnnotationTypes::TRUSTED_SOURCES]],
apssec_practice.getWebAttacks().getProtections()
);
web_apps[rule_config.getAssetName()] = web_app;
}
@@ -1271,7 +1280,8 @@ PolicyMakerUtils::createThreatPreventionPracticeSections(
current_identifier,
rule_config.getContext(),
policy,
rule_annotations
rule_annotations,
default_mode
);
createSnortSections(
@@ -1282,7 +1292,8 @@ PolicyMakerUtils::createThreatPreventionPracticeSections(
practice_id,
current_identifier,
policy,
rule_annotations
rule_annotations,
default_mode
);
createFileSecuritySections(
@@ -1292,11 +1303,18 @@ PolicyMakerUtils::createThreatPreventionPracticeSections(
rule_annotations[AnnotationTypes::PRACTICE],
"assetId(" + rule_config.getAssetId() + ")",
policy,
rule_annotations
rule_annotations,
default_mode
);
if (!web_apps.count(rule_config.getAssetName())) {
createWebAppSection(policy, rule_config, practice_id, asset_name, default_mode, rule_annotations);
createWebAppSection(
policy,
rule_config,
practice_id,
asset_name,
default_mode,
rule_annotations);
}
}
@@ -1568,6 +1586,7 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
std::get<0>(splited_host_name),
std::get<2>(splited_host_name),
log_triggers[rule_annotations[AnnotationTypes::TRIGGER]].getTriggerId(),
rule.getMode(),
policy,
rule_annotations
);