abcWebAcl Implementation¶
The abcWebAcl
construct, part of the abc-cdk-lib
, creates an AWS WebAcl (WAF) that conforms to company InfoSec requirements. This construct includes built-in rules that protect associated endpoints against common internet exploits. Some of these rules may conflict with valid application requests. To address these conflicts, this construct allows you to override specific rules, disable a rule group, or override a rule group when necessary.
The examples provided are intended to help you expedite the implementation of the abcWebAcl
construct. They include common configurations that your implementation might require. These examples represent a small subset of the many configurations possible for the abcWebAcl
. For more information, see the abc-cdk-lib/abc-waf guide. abcWebAcl
is available through abc-cdk-lib
versions 0.21.0 or higher.
Example abcWebAcl
const alb = new ApplicationLoadBalancer(this, 'alb', {...})
const webAcl = new abcWebAcl(this, 'WebAcl', {
workloadName: WORKLOAD_NAME,
resourceArn: alb.loadBalancerArn,
resourceType: abcWebACLResourceTypes.LOAD_BALANCER,
name: 'abc-waf-example',
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'abc-waf-example',
},
})
Diagram of abcWebAcl rules/rule group evaluation
Rule order¶
Rule groups are evaluated based on the following order:
- Information Security IP Deny List - IP Deny list managed by Information Security. This is a list of known bad actor IP addresses that are blocked from accessing the protected resource.
- Application Specific IP Deny List - IP Deny list managed by the Application team. This is a list of IP addresses the Application team requires to be blocked from access to the protected resource.
- Information Security IP Allow List - IP Allow list managed by Information Security. Addresses in this list will be allowed access to the protected resource and will not be evaluated by remaining WAF rules.
- Application Specific IP Allow List - IP Allow list managed by the Application team. This is a list of IP addresses the Application team explicitely authorized to access the protected resource. Remaining WAF Rules are not evaluated.
- Information Security GeoBlockingRule - This is a WAF rule that blocks access to countries that are not in the rule's Allow list. This rule contains an InfoSec Exception IP list and and Application Exception IP list where specific IP address ranges can be added, allowing access even from blocked countries.
- Application rules - These rules are defined by the Application team during the implementation of this construct. These rules are provided by the rules parameter. It's recommended that Application teams create rules with the
Block
action when building rules. - Information Security baseline post-rules - These rules are defined by Information Security. This list consists of:
AWSManagedRulesKnownBadInputsRuleSet
AWSManagedRulesCommonRuleSet
AWSManagedRulesSQLiRuleSet
AWSManagedRulesBotControlRuleSet
Rule evaluation¶
abcWebAcl rules and rule groups are processed according to the defined rule order. Each rule and rule group is associated with one of the following actions:
- Allow
- Block
- Count
These actions determine the response when criteria of the rule are met during evaluation. Allow and Block actions are terminating actions; the Count action acknowledges that the evaluation was true without terminating the process.
The abcWebAcl was designed for blocking rules, which means the rules are defined to block access to requests that meet the rule criteria. A request that matches any of the rule group's rules will be blocked and will not gain access to the underlying protected resource. Requests that do not meet the rule's criteria will be passed on to the next rule for evaluation. If none of the rules evaluated are true, the request will gain access to the underlying protected resource.
Note
It's highly recommended that rules created and added to the abcWebAcl
by application teams have the Block action. An Allow rule added as an application rule will allow access to the underlying protected resource if the rule evaluates to true. The remaining rules will not be evaluated, which may permit access to a request that would have been blocked by one of the remaining rules.
Example for using an Allow rule
An example of when an Allow rule is appropriate is a scenario involving a smart device that functions like Sono. In this situation, a request is made to a smart device service, which then makes calls on behalf of the device. The initial request passes the rule evaluation to reach the device service, which is an internal service that makes requests to the internal interface of the application load balancer. These requests do not need further rule evaluation.
To support this scenario, you'd do the following:
- Create an application IP set that includes the IP address range of the device services.
- Add the application IP set to the
InfosecGeoBlockingRule
. - Create a new rule with an Allow action and add it as an application rule to the
abcWebAcl
.
Any request that originates from an IP address in the application IP set will be granted access when the application rules are evaluated, and no further evaluation will occur.
Rule groups¶
The following rule groups are built into the abcWebAcl
construct:
-
InfosecGeoBlockingRule - An abc-managed Blocking rule group with a list of country codes that are allowed access to abc applications. Requests originating from countries outside of the list are blocked unless the request's specific IP address is in one of the exception IP set associated with the rule.
This rule has two exception IP sets to the country code evaluation. If a request's IP address is in either of the following IP sets, it bypasses the country code restriction, and processing continues to the next rule or rule group.
- abc Managed IP Set: This IP set includes exceptions identified by Information Security.
- Application IP Set: An optional parameter for the
abcWebACl
managed by the Application team. This IP set should include addresses you want to allow access, even if they originate from blocked countries.
-
AWSManagedRulesKnowBadInputsRuleSet - An AWS-managed Blocking rule group. It includes rules to block request patterns that are known to be invalid and are associated with exploitation or discovery of vulnerabilities. For more information, see AWS WAF Developer Guide: Known bad inputs managed rule group.
-
AWSManagedRulesCommonRuleSet - An AWS-managed Blocking rule group. It includes rules that are generally applicable to web applications. This provides protection against exploitation of a wide range of vulnerabilities, including some of the high risk and commonly occurring vulnerabilities described in OWASP publications, such as OWASP Top 10.
The following rules are known to potentially cause unexpected blocking and may need to be overridden for your implementation. Additional rules may also exist that require overrides for your implementation. For more information, see AWS WAF Developer Guide: Baseline rule groups.
Rule Description Notes NoUserAgent_HEADER Inspects for requests that are missing the HTTP User-Agent header. If API access is expected from non-browser applications then this rule should be overridden. SizeRestrictions_Cookie_HEADER Inspects for cookie headers that are over 10,240 bytes. SizeRestrictions_BODY Inspects for request bodies that are over 8 KB (8,192 bytes). If you expect a request body size > 8K then override this rule. EC2MetaDataSSRF_COOKIE Inspects for attempts to exfiltrate Amazon EC2 metadata from the request cookie. GenericLFI_BODY Inspects for the presence of Local File Inclusion (LFI) exploits in the request body. Examples include path traversal attempts using techniques like ../../. RestrictedExtensions_URIPATH Inspects for requests whose URI paths contain system file extensions that are unsafe to read or run. Example patterns include extensions like .log
and.ini
.CrossSiteScripting_BODY Inspects the request body for common cross-site scripting (XSS) patterns using the built-in AWS WAF Cross-site scripting attack rule statement. Example patterns include scripts like <script>alert("hello")</script>
. -
AWSManagedRulesBotControlRuleSet - An AWS-managed blocking rule group that includes rules to manage requests from bots.
The following rules are known to potentially cause unexpected blocking and may need to be overridden for your implementation. Additional rules may also exist that require overrides for your implementation. For more information, see AWS WAF Bot Control rule group.
Rule Description Notes CategoryHttpLibrary Inspects for requests that are generated by bots from the HTTP libraries of various programming languages. These may include API requests that you choose to allow or monitor. Blocks requests that are generated from HTTP libraries of various programming languages and may include API requests. We have verified that is blocks java and python request. SignalKnownBotDataCenter Inspects for indicators of data centers that are typically used by bots. Blocks requests that are non-browser requests, (curl, postman, gohttp, python) initiated from AWS. AWS is identified as a Bot Data center. If using non-browser requests then this should be overridden. SignalNonBrowserUserAgent Inspects for user agent strings that don't seem to be from a web browser. This category can include API requests. Blocks any request that does not appear to be from a web browser.
Initial implementation¶
When initially implementing the abcWebAcl construct we recommend overriding the following rule groups:
AWSManagedRulesKnownBadInputsRuleSet
AWSManagedRulesCommonRuleSet
AWSManagedRulesSQLiRuleSet
AWSManagedRulesBotControlRuleSet
Overriding rules changes the rule's action to Count to ensure the rule does not block any requests. You can then analyze each rule group to identify any rules within the group that would block valid requests. If you identify any of these rules, you can update the implementation to override only those specific rules instead of the entire rule group.
Implementation of abcWebAcl construct with override created for the rule groups
const alb = new ApplicationLoadBalancer(this, 'alb', {...})
const webAcl = new abcWebAcl(this, 'WebAcl', {
workloadName: WORKLOAD_NAME,
resourceArn: alb.loadBalancerArn,
resourceType: abcWebACLResourceTypes.LOAD_BALANCER,
name: 'abc-waf-example',
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'abc-waf-example',
},
managedRuleGroupOverrides: ['AWSManagedRulesCommonRuleSet', 'AWSManagedRulesCommonRuleSet','AWSManagedRulesSQLiRuleSet','AWSManagedRulesBotControlRuleSet'],
})
Overriding rule groups and rules¶
The rules built into abcWebAcl
are created to protect endpoints from common internet exploits. However, some of the provided rules may be in conflict with valid application requests and may need to be either overridden or disabled.
-
Override a rule group
Any rule group can be overridden. Overriding a rule group changes the rule action to Count(), so the rule is still evaluated, but the action is set to count the requests, rather than block or allow them.
Code sample - override rule group
const webAcl = new abcWebAcl(this, 'WebAcl', { workloadName: WORKLOAD_NAME, resourceArn: alb.loadBalancerArn, resourceType: abcWebACLResourceTypes.LOAD_BALANCER, name: 'abc-waf-example', visibilityConfig: { sampledRequestsEnabled: true, cloudWatchMetricsEnabled: true, metricName: 'WebAcl', }, managedRuleGroupOverrides: ['AWSManagedRulesSQLiRuleSet'], })
-
Override an individual rule of a rule group
Individual rules of a rule group can be overridden. When overriding an individual rule, the individual rule action is set to Count, so the rule is still evaluated, but the action is set to count the requests rather than block or allow them.
Code sample - Override individual rule
const webAcl = new abcWebAcl(this, 'WebAcl', { workloadName: WORKLOAD_NAME, resourceArn: alb.loadBalancerArn, resourceType: abcWebACLResourceTypes.LOAD_BALANCER, name: 'abc-waf-example', visibilityConfig: { sampledRequestsEnabled: true, cloudWatchMetricsEnabled: true, metricName: 'WebAcl', }, ruleGroupOverrides: [ { ruleGroupName: 'AWSManagedRulesCommonRuleSet', ruleActionOverrideProperties: [ { name: 'NoUserAgent_HEADER', actionToUse: { count: {}, }, }, ], }, ], })
-
Add allow/deny IP rule
You can configure additional IP sets to explicitly allow or deny certain IP addresses. These are configured using
applicationAllowIPSetList
orapplicationDenyIPSetList
. IP addresses in the allow list will bypass remaining application rules, rule groups, and InfoSec rule groups.Code sample - add allow/deny IP rule
const appAllowIPSet = new CfnIPSet(this, 'appAllowIPSet', { name: 'appAllowIPSet', addresses: [], ipAddressVersion: 'IPV4', scope: 'REGIONAL', }) const webAcl = new abcWebAcl(this, 'WebAcl', { workloadName: WORKLOAD_NAME, resourceArn: alb.loadBalancerArn, resourceType: abcWebACLResourceTypes.LOAD_BALANCER, name: 'abc-waf-example', visibilityConfig: { sampledRequestsEnabled: true, cloudWatchMetricsEnabled: true, metricName: 'WebAcl', }, applicationAllowIPSetList: [{ arn: appAllowIPSet.attrArn }], })
-
Add IP exceptions to the InfoSec Geoblocking rule
If a request originates from a country that is blocked,
abcWebAcl
allows users to configure IP address exclusions through thegeoblockRuleIPExceptionList
parameter.Code sample: Configure IP address exclusions
const geoblockExceptionIPSet = new CfnIPSet(this, 'geoExceptionIPSet', { name: 'geoExceptionIPSet', addresses: [], ipAddressVersion: 'IPV4', scope: 'REGIONAL', }) const webAcl = new abcWebAcl(this, 'WebAcl', { workloadName: WORKLOAD_NAME, resourceArn: alb.loadBalancerArn, resourceType: abcWebACLResourceTypes.LOAD_BALANCER, name: 'abc-waf-example', visibilityConfig: { sampledRequestsEnabled: true, cloudWatchMetricsEnabled: true, metricName: 'WebAcl', }, geoblockRuleIPExceptionList: [{ arn: geoblockExceptionIPSet.attrArn }], })
InfoSec's allowed countries list
//Version of ISO CODES supported can be found on this page: https://en.wikipedia.org/wiki/ISO_3166-2 export const INFOSEC_GEO_COUNTRIES_ALLOWED = [ 'AL', // Albania 'AD', // Andorra 'AR', // Argentina 'AM', // Armenia 'AU', // Australia 'AT', // Austria 'AZ', // Azerbaijan 'BY', // Belarus 'BE', // Belgium 'BA', // Bosnia and Herzegovina 'BR', // Brazil 'BG', // Bulgaria 'CA', // Canada 'CO', // Colombia 'CR', // Costa Rica 'HR', // Croatia 'CY', // Cyprus 'CZ', // Czechia 'DK', // Denmark 'DO', // Dominican Republic 'DO', // Dominican Republic 'EC', // Ecuador 'EE', // Estonia 'FI', // Finland 'FR', // France 'GE', // Georgia 'DE', // Germany 'GR', // Greece 'HU', // Hungary 'IS', // Iceland 'IN', // India 'IE', // Ireland 'IT', // Italy 'KZ', // Kazakhstan 'XK', // Kosovo 'LV', // Latvia 'LI', // Liechtenstein 'LT', // Lithuania 'LU', // Luxembourg 'MT', // Malta 'MU', // Mauritius 'MX', // Mexico 'MD', // Moldova 'MC', // Monaco 'ME', // Montenegro 'NL', // Netherlands 'MK', // North Macedonia 'NO', // Norway 'PL', // Poland 'PT', // Portugal 'PR', // Puerto Rico 'RO', // Romania 'SM', // San Marino 'RS', // Serbia 'SK', // Slovakia 'SI', // Slovenia 'ES', // Spain 'SE', // Sweden 'CH', // Switzerland 'TR', // Turkey 'GB', // UK / Great Britain 'US', // USA 'VA', // Vatican City ]
Adding application specific rules¶
Application specific rules can be added to the WebAcl. These rules are evaluated after Network Engineering and Information Security pre-rules are evaluated.
Code sample: Add application specific rules
const webAcl = new abcWebAcl(this, 'WebAcl', {
workloadName: WORKLOAD_NAME,
resourceArn: alb.loadBalancerArn,
resourceType: abcWebACLResourceTypes.LOAD_BALANCER,
name: 'abc-waf-example',
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'WebAcl',
},
rules: [
{
name: 'AWSManagedRulesAmazonIpReputationList',
priority: 10,
overrideAction: { none: {} },
statement: {
managedRuleGroupStatement: {
vendorName: 'AWS',
name: 'AWSManagedRulesAmazonIpReputationList',
ruleActionOverrides: [
{
name: 'AWSManagedIPReputationList',
actionToUse: {
count: {},
},
},
],
},
},
visibilityConfig: {
sampledRequestsEnabled: true,
cloudWatchMetricsEnabled: true,
metricName: 'AWSManagedRulesAmazonIpReputationList',
},
},
],
})
Additional resources