This solution automatically deploys a single web access control list (web ACL) with a set of AWS WAF rules designed to filter common web-based attacks.
The configure_web_acl method in custom-resource.py does not handle changing the action of an associated rule. One might want to use COUNT action first for some rule to learn what effect it would have and then later switch it to BLOCK.
To support this, a method like this is needed:
def process_rule_action_change(new_action, protection_tag_name, rule_name, resource_properties, old_resource_properties, current_rules):
logging.getLogger().info("[process_rule_action_change] Start")
updates = []
rule_id = old_resource_properties[rule_name] if rule_name in old_resource_properties else None
rule_data = current_rules[rule_id] if rule_id in current_rules else None
old_action = rule_data['Action']['Type'] if rule_data is not None else None
is_activated = resource_properties[protection_tag_name] == "yes"
was_activated = old_resource_properties[protection_tag_name] == "yes"
if was_activated and is_activated and rule_id in current_rules and (old_action != new_action):
delete = {
'Action': 'DELETE',
'ActivatedRule': {
'Priority': rule_data['Priority'],
'RuleId': rule_id,
'Action': rule_data['Action'],
'Type': rule_data['Type']
}
}
insert = {
'Action': 'INSERT',
'ActivatedRule': {
'Priority': rule_data['Priority'],
'RuleId': rule_id,
'Action': {'Type': new_action},
'Type': rule_data['Type']
}
}
# We need to first delete the rule with the old action
updates.append(delete)
# And immediately insert it with the new action
updates.append(insert)
logging.getLogger().info(
"rule action changed".format(json.dumps(updates)))
logging.getLogger().info("[process_rule_action_change] End")
return updates
This kind of new code block needs to be added to configure_web_acl right before the existing update_web_acl call:
if old_resource_properties:
updates.extend(process_rule_action_change(resource_properties['ActionWAFSqlInjectionRule'], 'ProtectionActivatedSqlInjection', 'WAFSqlInjectionRule', resource_properties, old_resource_properties, current_rules))
updates.extend(process_rule_action_change(resource_properties['ActionWAFXssRule'], 'ProtectionActivatedCrossSiteScripting', 'WAFXssRule', resource_properties, old_resource_properties, current_rules))
updates.extend(process_rule_action_change(resource_properties['ActionWAFHttpFloodRateBasedRule'], 'ProtectionActivatedHttpFloodRateBased', 'WAFHttpFloodRateBasedRule', resource_properties, old_resource_properties, current_rules))
updates.extend(process_rule_action_change(resource_properties['ActionWAFHttpFloodRegularRule'], 'ProtectionActivatedHttpFloodRegular', 'WAFHttpFloodRegularRule', resource_properties, old_resource_properties, current_rules))
updates.extend(process_rule_action_change(resource_properties['ActionWAFScannersProbesRule'], 'ProtectionActivatedScannersProbes', 'WAFScannersProbesRule', resource_properties, old_resource_properties, current_rules))
updates.extend(process_rule_action_change(resource_properties['ActionWAFIPReputationListsRule'], 'ProtectionActivatedReputationLists', 'WAFIPReputationListsRule', resource_properties, old_resource_properties, current_rules))
updates.extend(process_rule_action_change(resource_properties['ActionWAFBadBotRule'], 'ProtectionActivatedBadBot', 'WAFBadBotRule', resource_properties, old_resource_properties, current_rules))
updates = [u for u in updates if u is not None]
logging.getLogger().info("updates: {}".format(json.dumps(updates)))
#------------------------------------------------------------------------------------------------------------------
# Update WebACL
#------------------------------------------------------------------------------------------------------------------
update_web_acl(resource_properties['WAFWebACL'], updates)
Thanks for sharing the code. The out-of-box solution currently doesn't support change of action. Closing this old ticket. Feel free to open a new one if needed.
The configure_web_acl method in custom-resource.py does not handle changing the action of an associated rule. One might want to use COUNT action first for some rule to learn what effect it would have and then later switch it to BLOCK.
To support this, a method like this is needed:
This kind of new code block needs to be added to configure_web_acl right before the existing update_web_acl call: