@kensio/yulin 1.21.22 → 1.21.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/service/athena/engine/sim-athena-ast-nodes.d.ts +11 -0
- package/dist/service/athena/engine/sim-athena-ast-nodes.js +22 -0
- package/dist/service/athena/engine/sim-athena-string-shims.js +29 -1
- package/dist/service/athena/engine/sim-athena-unnest-item.js +6 -15
- package/dist/service/athena/engine/sim-athena-unnest-rewrite.d.ts +4 -4
- package/dist/service/athena/engine/sim-athena-unnest-rewrite.js +4 -4
- package/dist/service/athena/engine/sim-athena-unnest-source.d.ts +10 -9
- package/dist/service/athena/engine/sim-athena-unnest-source.js +25 -11
- package/dist/service/athena/sim-athena-flattened-events.fixture.d.ts +3 -0
- package/dist/service/athena/sim-athena-flattened-events.fixture.js +46 -0
- package/dist/service/wafv2/association/sim-aws-waf-protected-resources.js +4 -0
- package/dist/service/wafv2/association/sim-waf-associations.d.ts +6 -0
- package/dist/service/wafv2/association/sim-waf-associations.js +17 -0
- package/dist/service/wafv2/association/sim-waf-protected-resource.d.ts +13 -8
- package/dist/service/wafv2/association/sim-waf-protected-resource.js +23 -23
- package/dist/service/wafv2/association/sim-waf-protected-resources.d.ts +11 -6
- package/dist/service/wafv2/association/sim-waf-protected-resources.js +10 -7
- package/dist/service/wafv2/association/sim-waf-unsimulated-resource.d.ts +33 -0
- package/dist/service/wafv2/association/sim-waf-unsimulated-resource.js +66 -0
- package/dist/service/wafv2/cfn/association/sim-cfn-waf-association-creator.js +5 -0
- package/dist/service/wafv2/cfn/ip-set/sim-cfn-waf-ip-set-config.js +1 -0
- package/dist/service/wafv2/cfn/ip-set/sim-cfn-waf-ip-set-creator.js +2 -0
- package/dist/service/wafv2/cfn/regex-pattern-set/sim-cfn-waf-regex-set-config.js +1 -0
- package/dist/service/wafv2/cfn/regex-pattern-set/sim-cfn-waf-regex-set-creator.js +2 -0
- package/dist/service/wafv2/cfn/sim-cfn-waf-resource-config.d.ts +4 -0
- package/dist/service/wafv2/cfn/sim-cfn-waf-resource-config.js +10 -0
- package/dist/service/wafv2/cfn/sim-cfn-waf-unsimulated.d.ts +10 -0
- package/dist/service/wafv2/cfn/sim-cfn-waf-unsimulated.js +12 -0
- package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-config.d.ts +1 -13
- package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-config.js +8 -21
- package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-creator.d.ts +4 -9
- package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-web-acl-creator.js +7 -15
- package/dist/service/wafv2/command/association/sim-wafv2-association-commands.js +2 -1
- package/dist/service/wafv2/command/association/sim-wafv2-association-input.d.ts +10 -2
- package/dist/service/wafv2/command/association/sim-wafv2-association-input.js +25 -13
- package/dist/service/wafv2/command/ip-set/sim-wafv2-ip-set-commands.d.ts +3 -3
- package/dist/service/wafv2/command/ip-set/sim-wafv2-ip-set-commands.js +5 -5
- package/dist/service/wafv2/command/managed-rule-group/sim-wafv2-managed-rule-group-commands.js +4 -4
- package/dist/service/wafv2/command/regex-pattern-set/sim-wafv2-regex-pattern-set-commands.js +2 -2
- package/dist/service/wafv2/command/sim-wafv2-input.d.ts +0 -7
- package/dist/service/wafv2/command/sim-wafv2-input.js +1 -13
- package/dist/service/wafv2/command/web-acl/sim-waf-web-acl-output.js +1 -0
- package/dist/service/wafv2/command/web-acl/sim-wafv2-unsimulated-web-acl-input.d.ts +9 -12
- package/dist/service/wafv2/command/web-acl/sim-wafv2-unsimulated-web-acl-input.js +27 -28
- package/dist/service/wafv2/command/web-acl/sim-wafv2-web-acl-commands.d.ts +3 -3
- package/dist/service/wafv2/command/web-acl/sim-wafv2-web-acl-commands.js +6 -6
- package/dist/service/wafv2/command/web-acl/web-acl.command.d.ts +6 -0
- package/dist/service/wafv2/index.d.ts +3 -0
- package/dist/service/wafv2/index.js +1 -0
- package/dist/service/wafv2/managed/group/sim-waf-bot-control.d.ts +27 -0
- package/dist/service/wafv2/managed/group/sim-waf-bot-control.js +68 -0
- package/dist/service/wafv2/managed/group/sim-waf-ip-reputation.d.ts +18 -0
- package/dist/service/wafv2/managed/group/sim-waf-ip-reputation.js +51 -0
- package/dist/service/wafv2/managed/sim-waf-bot-declaration.d.ts +35 -0
- package/dist/service/wafv2/managed/sim-waf-bot-declaration.js +42 -0
- package/dist/service/wafv2/managed/sim-waf-managed-declaration.d.ts +35 -0
- package/dist/service/wafv2/managed/sim-waf-managed-declaration.js +30 -0
- package/dist/service/wafv2/managed/sim-waf-managed-group-configs.d.ts +11 -0
- package/dist/service/wafv2/managed/sim-waf-managed-group-configs.js +42 -0
- package/dist/service/wafv2/managed/sim-waf-managed-group-input.d.ts +5 -4
- package/dist/service/wafv2/managed/sim-waf-managed-group-input.js +7 -9
- package/dist/service/wafv2/managed/sim-waf-managed-group-statement.js +16 -14
- package/dist/service/wafv2/managed/sim-waf-managed-group.type.d.ts +2 -2
- package/dist/service/wafv2/managed/sim-waf-managed-rule-actions.d.ts +30 -0
- package/dist/service/wafv2/managed/sim-waf-managed-rule-actions.js +26 -0
- package/dist/service/wafv2/managed/sim-waf-managed-rule-groups.d.ts +5 -3
- package/dist/service/wafv2/managed/sim-waf-managed-rule-groups.js +10 -3
- package/dist/service/wafv2/managed/sim-waf-managed-rule.type.d.ts +11 -2
- package/dist/service/wafv2/managed/sim-waf-managed-rules.d.ts +14 -9
- package/dist/service/wafv2/managed/sim-waf-managed-rules.js +15 -5
- package/dist/service/wafv2/resource/sim-waf-resource.d.ts +10 -0
- package/dist/service/wafv2/resource/sim-waf-resource.js +12 -0
- package/dist/service/wafv2/resource/sim-waf-unsimulated-part.d.ts +24 -0
- package/dist/service/wafv2/resource/sim-waf-unsimulated-part.js +8 -0
- package/dist/service/wafv2/sim-wafv2.d.ts +12 -12
- package/dist/service/wafv2/sim-wafv2.fixture.d.ts +19 -1
- package/dist/service/wafv2/sim-wafv2.fixture.js +29 -0
- package/dist/service/wafv2/sim-wafv2.js +25 -23
- package/dist/service/wafv2/statement/sim-waf-field-to-match.type.d.ts +2 -2
- package/dist/service/wafv2/statement/sim-waf-rule-refusals.d.ts +6 -4
- package/dist/service/wafv2/statement/sim-waf-rule-refusals.js +7 -6
- package/dist/service/wafv2/statement/sim-waf-statement.d.ts +3 -3
- package/dist/service/wafv2/statement/sim-waf-statement.js +3 -3
- package/dist/service/wafv2/statement/sim-waf-statement.type.d.ts +3 -3
- package/dist/service/wafv2/statement/sim-waf-unsimulated-statement.js +1 -1
- package/dist/service/wafv2/web-acl/sim-waf-association-config.d.ts +14 -7
- package/dist/service/wafv2/web-acl/sim-waf-association-config.js +17 -27
- package/dist/service/wafv2/web-acl/sim-waf-rule.d.ts +15 -3
- package/dist/service/wafv2/web-acl/sim-waf-rule.js +46 -10
- package/dist/service/wafv2/web-acl/sim-waf-statement-capacity.d.ts +4 -4
- package/dist/service/wafv2/web-acl/sim-waf-statement-capacity.js +4 -4
- package/dist/service/wafv2/web-acl/sim-waf-unsimulated-body-limit.d.ts +6 -0
- package/dist/service/wafv2/web-acl/sim-waf-unsimulated-body-limit.js +23 -0
- package/dist/service/wafv2/web-acl/sim-waf-web-acl-capacity.js +2 -2
- package/dist/service/wafv2/web-acl/sim-waf-web-acl-configuration.d.ts +5 -0
- package/dist/service/wafv2/web-acl/sim-waf-web-acl.d.ts +11 -2
- package/dist/service/wafv2/web-acl/sim-waf-web-acl.js +20 -1
- package/docs/services/athena/README.md +21 -2
- package/docs/services/wafv2/README.md +243 -51
- package/package.json +2 -2
- package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-evaluatable-rules.d.ts +0 -15
- package/dist/service/wafv2/cfn/web-acl/sim-cfn-waf-evaluatable-rules.js +0 -21
- package/dist/service/wafv2/web-acl/sim-waf-unevaluatable-rules.d.ts +0 -25
- package/dist/service/wafv2/web-acl/sim-waf-unevaluatable-rules.js +0 -33
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
import { SimWafUnsimulatedInputException } from "../../error/sim-wafv2.error.js";
|
|
2
|
-
import { refuseSimWafTags } from "../sim-wafv2-input.js";
|
|
3
1
|
const tokenActions = "the CAPTCHA and Challenge actions are answered by a browser, and nothing " +
|
|
4
2
|
"in a test does that";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Why each web ACL member this simulation does not model is held and not
|
|
5
|
+
* acted on, by the name a request and a template both write.
|
|
6
|
+
*/
|
|
7
|
+
const unsimulatedMembers = new Map([
|
|
8
|
+
["CaptchaConfig", tokenActions],
|
|
9
|
+
["ChallengeConfig", tokenActions],
|
|
10
|
+
["TokenDomains", tokenActions],
|
|
9
11
|
[
|
|
10
|
-
(input) => input.DataProtectionConfig,
|
|
11
12
|
"DataProtectionConfig",
|
|
12
13
|
"it decides what a request field looks like in logs, and web ACL logging " +
|
|
13
14
|
"is not simulated",
|
|
14
15
|
],
|
|
15
16
|
[
|
|
16
|
-
(input) => input.OnSourceDDoSProtectionConfig,
|
|
17
17
|
"OnSourceDDoSProtectionConfig",
|
|
18
18
|
"it responds to traffic volume, which a simulated request never has",
|
|
19
19
|
],
|
|
20
20
|
[
|
|
21
|
-
(input) => input.ApplicationConfig,
|
|
22
21
|
"ApplicationConfig",
|
|
23
22
|
"it configures the WAF-hosted sign-in pages, which are not simulated",
|
|
24
23
|
],
|
|
25
|
-
];
|
|
24
|
+
]);
|
|
26
25
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* The web ACL members a write carries that this simulation holds without
|
|
27
|
+
* acting on, keyed by member name.
|
|
29
28
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
29
|
+
* Each of them changes what a web ACL does on real WAF. The web ACL keeps
|
|
30
|
+
* them, `GetWebACL` returns them as written, and `unsimulatedSimWafWebAclMembers`
|
|
31
|
+
* says which ones a request evaluated here goes without.
|
|
33
32
|
*/
|
|
34
|
-
export
|
|
33
|
+
export function heldSimWafWebAclMembers(input) {
|
|
34
|
+
return Object.fromEntries(Object.entries(input).filter(([member, value]) => unsimulatedMembers.has(member) && value !== undefined));
|
|
35
|
+
}
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* Each of them changes what a web ACL does on real WAF, so accepting one and
|
|
39
|
-
* dropping it would leave the web ACL looking configured to the request that
|
|
40
|
-
* wrote it and unconfigured to every request it then evaluated.
|
|
37
|
+
* What a web ACL's held members leave out, one part per member.
|
|
41
38
|
*/
|
|
42
|
-
export function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
export function unsimulatedSimWafWebAclMembers(members) {
|
|
40
|
+
return unsimulatedMembers
|
|
41
|
+
.entries()
|
|
42
|
+
.filter(([member]) => Object.hasOwn(members, member))
|
|
43
|
+
.map(([member, reason]) => ({
|
|
44
|
+
part: member,
|
|
45
|
+
reason: `${member} is not simulated: ${reason}`,
|
|
46
|
+
}))
|
|
47
|
+
.toArray();
|
|
49
48
|
}
|
|
@@ -20,9 +20,9 @@ interface SimWafWebAclCommandsProperties {
|
|
|
20
20
|
/**
|
|
21
21
|
* The commands that make, read, list, change and remove web ACLs.
|
|
22
22
|
*
|
|
23
|
-
* Every rule is compiled where the web ACL is written
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* Every rule is compiled where the web ACL is written. A rule or member this
|
|
24
|
+
* simulation cannot act on is held as written, so `GetWebACL` returns it, and
|
|
25
|
+
* the web ACL reports it in `unsimulated`.
|
|
26
26
|
*/
|
|
27
27
|
export declare class SimWafWebAclCommands {
|
|
28
28
|
#private;
|
|
@@ -4,14 +4,14 @@ import { SimWafWebAcl } from "../../web-acl/sim-waf-web-acl.js";
|
|
|
4
4
|
import { SimWafPage } from "../sim-wafv2-page.js";
|
|
5
5
|
import { checkedSimWafDescription, requiredSimWafName, } from "../sim-wafv2-input.js";
|
|
6
6
|
import { requireSimWafResource, } from "../sim-wafv2-resource-lookup.js";
|
|
7
|
-
import {
|
|
7
|
+
import { heldSimWafWebAclMembers } from "./sim-wafv2-unsimulated-web-acl-input.js";
|
|
8
8
|
import { simWafWebAclOutput } from "./sim-waf-web-acl-output.js";
|
|
9
9
|
/**
|
|
10
10
|
* The commands that make, read, list, change and remove web ACLs.
|
|
11
11
|
*
|
|
12
|
-
* Every rule is compiled where the web ACL is written
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Every rule is compiled where the web ACL is written. A rule or member this
|
|
13
|
+
* simulation cannot act on is held as written, so `GetWebACL` returns it, and
|
|
14
|
+
* the web ACL reports it in `unsimulated`.
|
|
15
15
|
*/
|
|
16
16
|
export class SimWafWebAclCommands {
|
|
17
17
|
#webAcls;
|
|
@@ -37,7 +37,6 @@ export class SimWafWebAclCommands {
|
|
|
37
37
|
const { input } = command;
|
|
38
38
|
const name = requiredSimWafName(input.Name);
|
|
39
39
|
const scope = requiredSimWafScope(input.Scope, this.#accountRegionScope.regionName);
|
|
40
|
-
refuseUnsimulatedSimWafWebAclInput(input, "CreateWebACL");
|
|
41
40
|
const configuration = configurationOf(input);
|
|
42
41
|
const webAcl = new SimWafWebAcl({
|
|
43
42
|
name,
|
|
@@ -45,6 +44,7 @@ export class SimWafWebAclCommands {
|
|
|
45
44
|
accountRegionScope: this.#accountRegionScope,
|
|
46
45
|
description: configuration.description,
|
|
47
46
|
configuration,
|
|
47
|
+
tags: input.Tags,
|
|
48
48
|
regexPatternSets: this.#regexPatternSets,
|
|
49
49
|
managedRules: this.#managedRules,
|
|
50
50
|
clock: this.#clock,
|
|
@@ -68,7 +68,6 @@ export class SimWafWebAclCommands {
|
|
|
68
68
|
*/
|
|
69
69
|
updateWebAcl(command, options) {
|
|
70
70
|
const { input } = command;
|
|
71
|
-
refuseUnsimulatedSimWafWebAclInput(input, "UpdateWebACL");
|
|
72
71
|
const configuration = configurationOf(input);
|
|
73
72
|
const webAcl = this.require(input, "wafv2:UpdateWebACL", options);
|
|
74
73
|
webAcl.reconfigure(configuration, input.LockToken);
|
|
@@ -138,5 +137,6 @@ function configurationOf(input) {
|
|
|
138
137
|
visibilityConfig: input.VisibilityConfig,
|
|
139
138
|
description: checkedSimWafDescription(input.Description),
|
|
140
139
|
associationConfig: input.AssociationConfig,
|
|
140
|
+
heldMembers: heldSimWafWebAclMembers(input),
|
|
141
141
|
};
|
|
142
142
|
}
|
|
@@ -74,6 +74,12 @@ export interface SimWafWebAclOutput {
|
|
|
74
74
|
readonly VisibilityConfig: unknown;
|
|
75
75
|
readonly CustomResponseBodies: SimWafCustomResponseBodies | undefined;
|
|
76
76
|
readonly AssociationConfig: SimWafAssociationConfigInput | undefined;
|
|
77
|
+
readonly CaptchaConfig?: unknown;
|
|
78
|
+
readonly ChallengeConfig?: unknown;
|
|
79
|
+
readonly TokenDomains?: readonly string[] | undefined;
|
|
80
|
+
readonly DataProtectionConfig?: unknown;
|
|
81
|
+
readonly OnSourceDDoSProtectionConfig?: unknown;
|
|
82
|
+
readonly ApplicationConfig?: unknown;
|
|
77
83
|
}
|
|
78
84
|
export interface SimGetWebAclCommandOutput {
|
|
79
85
|
readonly WebACL?: SimWafWebAclOutput | undefined;
|
|
@@ -11,6 +11,8 @@ export { SimWafNoProtection, type SimWafProtectedRequest, type SimWafProtection,
|
|
|
11
11
|
export { SimWafInspected, SimWafRequestInspection, } from "./association/sim-waf-request-inspection.js";
|
|
12
12
|
export { SimWafRestApiStage } from "./association/sim-waf-rest-api-stage.js";
|
|
13
13
|
export { SimWafUserPool } from "./association/sim-waf-user-pool.js";
|
|
14
|
+
export { SimWafUnsimulatedResource, type SimWafUnsimulatedResourceType, simWafUnsimulatedResourceTypes, } from "./association/sim-waf-unsimulated-resource.js";
|
|
15
|
+
export type { SimWafUnsimulatedPart } from "./resource/sim-waf-unsimulated-part.js";
|
|
14
16
|
export { SimWafResource, type SimWafResourceSummary, } from "./resource/sim-waf-resource.js";
|
|
15
17
|
export { SimWafWebAcl } from "./web-acl/sim-waf-web-acl.js";
|
|
16
18
|
export type { SimWafWebAclConfiguration } from "./web-acl/sim-waf-web-acl-configuration.js";
|
|
@@ -24,6 +26,7 @@ export { SimWafRegexPatternSet } from "./regex-pattern-set/sim-waf-regex-pattern
|
|
|
24
26
|
export type { SimWafDecision } from "./evaluate/sim-waf-decision.js";
|
|
25
27
|
export { SimWafRequestLabels } from "./evaluate/sim-waf-request-labels.js";
|
|
26
28
|
export { SimWafManagedRules, type SimWafManagedMatchDeclaration, } from "./managed/sim-waf-managed-rules.js";
|
|
29
|
+
export type { SimWafBotDeclaration } from "./managed/sim-waf-bot-declaration.js";
|
|
27
30
|
export type { SimWafManagedRuleReport } from "./managed/sim-waf-managed-rule-report.js";
|
|
28
31
|
export type { SimWafManagedRuleTier } from "./managed/sim-waf-managed-rule.type.js";
|
|
29
32
|
export type { SimWafManagedRuleGroupStatementInput, SimWafOverrideActionInput, SimWafRuleActionOverrideInput, } from "./managed/sim-waf-managed-group.type.js";
|
|
@@ -9,6 +9,7 @@ export { SimWafNoProtection, } from "./association/sim-waf-protection.js";
|
|
|
9
9
|
export { SimWafInspected, SimWafRequestInspection, } from "./association/sim-waf-request-inspection.js";
|
|
10
10
|
export { SimWafRestApiStage } from "./association/sim-waf-rest-api-stage.js";
|
|
11
11
|
export { SimWafUserPool } from "./association/sim-waf-user-pool.js";
|
|
12
|
+
export { SimWafUnsimulatedResource, simWafUnsimulatedResourceTypes, } from "./association/sim-waf-unsimulated-resource.js";
|
|
12
13
|
export { SimWafResource, } from "./resource/sim-waf-resource.js";
|
|
13
14
|
export { SimWafWebAcl } from "./web-acl/sim-waf-web-acl.js";
|
|
14
15
|
export { SimWafRule } from "./web-acl/sim-waf-rule.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SimWafManagedRuleGroupDefinition } from "../sim-waf-managed-rule.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* The bot categories Bot Control's common level names, each with the rule
|
|
4
|
+
* that matches an unverified bot of that category.
|
|
5
|
+
*
|
|
6
|
+
* The category is spelled the way the `bot:category:` label spells it, and
|
|
7
|
+
* the rule name is `Category` and the category in Pascal case.
|
|
8
|
+
*/
|
|
9
|
+
export declare const simWafBotCategories: ReadonlyMap<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* The one category whose rule matches a verified bot as well.
|
|
12
|
+
*/
|
|
13
|
+
export declare const simWafBotCategoryMatchingVerified = "ai";
|
|
14
|
+
/**
|
|
15
|
+
* AWS WAF Bot Control at its common inspection level.
|
|
16
|
+
*
|
|
17
|
+
* The common level identifies a bot by what the request says about itself,
|
|
18
|
+
* and AWS publishes the rule names, the categories and the labels and none of
|
|
19
|
+
* the signatures. Verifying a bot reads the source address, which is
|
|
20
|
+
* `127.0.0.1` for every request here. So every rule is declared-only, and a
|
|
21
|
+
* test says which bot sent a request with `managedRules().onRequest` and a
|
|
22
|
+
* `bot` declaration.
|
|
23
|
+
*
|
|
24
|
+
* The targeted level is held without being evaluated. Its rules read tokens,
|
|
25
|
+
* browser signals and traffic across requests.
|
|
26
|
+
*/
|
|
27
|
+
export declare const simWafBotControlRuleSet: SimWafManagedRuleGroupDefinition;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bot categories Bot Control's common level names, each with the rule
|
|
3
|
+
* that matches an unverified bot of that category.
|
|
4
|
+
*
|
|
5
|
+
* The category is spelled the way the `bot:category:` label spells it, and
|
|
6
|
+
* the rule name is `Category` and the category in Pascal case.
|
|
7
|
+
*/
|
|
8
|
+
export const simWafBotCategories = new Map([
|
|
9
|
+
["advertising", "CategoryAdvertising"],
|
|
10
|
+
["archiver", "CategoryArchiver"],
|
|
11
|
+
["content_fetcher", "CategoryContentFetcher"],
|
|
12
|
+
["email_client", "CategoryEmailClient"],
|
|
13
|
+
["http_library", "CategoryHttpLibrary"],
|
|
14
|
+
["link_checker", "CategoryLinkChecker"],
|
|
15
|
+
["miscellaneous", "CategoryMiscellaneous"],
|
|
16
|
+
["monitoring", "CategoryMonitoring"],
|
|
17
|
+
["page_preview", "CategoryPagePreview"],
|
|
18
|
+
["scraping_framework", "CategoryScrapingFramework"],
|
|
19
|
+
["search_engine", "CategorySearchEngine"],
|
|
20
|
+
["security", "CategorySecurity"],
|
|
21
|
+
["seo", "CategorySeo"],
|
|
22
|
+
["social_media", "CategorySocialMedia"],
|
|
23
|
+
["webhooks", "CategoryWebhooks"],
|
|
24
|
+
["ai", "CategoryAI"],
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* The one category whose rule matches a verified bot as well.
|
|
28
|
+
*/
|
|
29
|
+
export const simWafBotCategoryMatchingVerified = "ai";
|
|
30
|
+
const signals = [
|
|
31
|
+
["SignalAutomatedBrowser", "automated_browser"],
|
|
32
|
+
["SignalKnownBotDataCenter", "known_bot_data_center"],
|
|
33
|
+
["SignalNonBrowserUserAgent", "non_browser_user_agent"],
|
|
34
|
+
];
|
|
35
|
+
const categoryRules = simWafBotCategories
|
|
36
|
+
.entries()
|
|
37
|
+
.map(([category, name]) => ({
|
|
38
|
+
name,
|
|
39
|
+
label: name,
|
|
40
|
+
labels: [`bot:category:${category}`],
|
|
41
|
+
tier: "declared",
|
|
42
|
+
}))
|
|
43
|
+
.toArray();
|
|
44
|
+
const signalRules = signals.map(([name, signal]) => ({
|
|
45
|
+
name,
|
|
46
|
+
label: name,
|
|
47
|
+
labels: [`signal:${signal}`],
|
|
48
|
+
tier: "declared",
|
|
49
|
+
}));
|
|
50
|
+
/**
|
|
51
|
+
* AWS WAF Bot Control at its common inspection level.
|
|
52
|
+
*
|
|
53
|
+
* The common level identifies a bot by what the request says about itself,
|
|
54
|
+
* and AWS publishes the rule names, the categories and the labels and none of
|
|
55
|
+
* the signatures. Verifying a bot reads the source address, which is
|
|
56
|
+
* `127.0.0.1` for every request here. So every rule is declared-only, and a
|
|
57
|
+
* test says which bot sent a request with `managedRules().onRequest` and a
|
|
58
|
+
* `bot` declaration.
|
|
59
|
+
*
|
|
60
|
+
* The targeted level is held without being evaluated. Its rules read tokens,
|
|
61
|
+
* browser signals and traffic across requests.
|
|
62
|
+
*/
|
|
63
|
+
export const simWafBotControlRuleSet = {
|
|
64
|
+
name: "AWSManagedRulesBotControlRuleSet",
|
|
65
|
+
labelNamespace: "awswaf:managed:aws:bot-control",
|
|
66
|
+
capacity: 50,
|
|
67
|
+
rules: [...categoryRules, ...signalRules],
|
|
68
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SimWafManagedRuleGroupDefinition } from "../sim-waf-managed-rule.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* The Amazon IP reputation list, which decides by the address a request came
|
|
4
|
+
* from.
|
|
5
|
+
*
|
|
6
|
+
* Every request in this simulation reports a source address of `127.0.0.1`,
|
|
7
|
+
* so every rule here is declared-only. A test says which requests come from a
|
|
8
|
+
* flagged address with `managedRules().onRequest`, and the group labels and
|
|
9
|
+
* acts on them as AWS documents.
|
|
10
|
+
*/
|
|
11
|
+
export declare const simWafIpReputationList: SimWafManagedRuleGroupDefinition;
|
|
12
|
+
/**
|
|
13
|
+
* The anonymous IP list, for VPNs, proxies, Tor nodes and hosting providers.
|
|
14
|
+
*
|
|
15
|
+
* It decides by source address as the reputation list does, and every rule is
|
|
16
|
+
* declared-only for the same reason.
|
|
17
|
+
*/
|
|
18
|
+
export declare const simWafAnonymousIpList: SimWafManagedRuleGroupDefinition;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Amazon IP reputation list, which decides by the address a request came
|
|
3
|
+
* from.
|
|
4
|
+
*
|
|
5
|
+
* Every request in this simulation reports a source address of `127.0.0.1`,
|
|
6
|
+
* so every rule here is declared-only. A test says which requests come from a
|
|
7
|
+
* flagged address with `managedRules().onRequest`, and the group labels and
|
|
8
|
+
* acts on them as AWS documents.
|
|
9
|
+
*/
|
|
10
|
+
export const simWafIpReputationList = {
|
|
11
|
+
name: "AWSManagedRulesAmazonIpReputationList",
|
|
12
|
+
labelNamespace: "awswaf:managed:aws:amazon-ip-list",
|
|
13
|
+
capacity: 25,
|
|
14
|
+
rules: [
|
|
15
|
+
{
|
|
16
|
+
name: "AWSManagedIPReputationList",
|
|
17
|
+
label: "AWSManagedIPReputationList",
|
|
18
|
+
tier: "declared",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "AWSManagedReconnaissanceList",
|
|
22
|
+
label: "AWSManagedReconnaissanceList",
|
|
23
|
+
tier: "declared",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "AWSManagedIPDDoSList",
|
|
27
|
+
label: "AWSManagedIPDDoSList",
|
|
28
|
+
counts: true,
|
|
29
|
+
tier: "declared",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The anonymous IP list, for VPNs, proxies, Tor nodes and hosting providers.
|
|
35
|
+
*
|
|
36
|
+
* It decides by source address as the reputation list does, and every rule is
|
|
37
|
+
* declared-only for the same reason.
|
|
38
|
+
*/
|
|
39
|
+
export const simWafAnonymousIpList = {
|
|
40
|
+
name: "AWSManagedRulesAnonymousIpList",
|
|
41
|
+
labelNamespace: "awswaf:managed:aws:anonymous-ip-list",
|
|
42
|
+
capacity: 50,
|
|
43
|
+
rules: [
|
|
44
|
+
{ name: "AnonymousIPList", label: "AnonymousIPList", tier: "declared" },
|
|
45
|
+
{
|
|
46
|
+
name: "HostingProviderIPList",
|
|
47
|
+
label: "HostingProviderIPList",
|
|
48
|
+
tier: "declared",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bot a test says sent a request, as Bot Control would identify it.
|
|
3
|
+
*/
|
|
4
|
+
export interface SimWafBotDeclaration {
|
|
5
|
+
/**
|
|
6
|
+
* The category, spelled as the `bot:category:` label spells it, such as
|
|
7
|
+
* `search_engine` or `http_library`.
|
|
8
|
+
*/
|
|
9
|
+
readonly category: string;
|
|
10
|
+
/** The bot's name, as the `bot:name:` label spells it, such as `googlebot`. */
|
|
11
|
+
readonly name?: string | undefined;
|
|
12
|
+
/** The bot's publisher, as the `bot:organization:` label spells it. */
|
|
13
|
+
readonly organization?: string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Whether Bot Control could verify the bot. A verified bot is labelled and
|
|
16
|
+
* left alone, and an unverified one matches its category's rule.
|
|
17
|
+
*/
|
|
18
|
+
readonly verified?: boolean | undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* What one declared bot adds to a request: the rules that match it, and the
|
|
22
|
+
* labels the group adds whether or not a rule matches.
|
|
23
|
+
*/
|
|
24
|
+
export interface SimWafBotDeclared {
|
|
25
|
+
readonly matches: readonly string[];
|
|
26
|
+
readonly groupLabels: ReadonlyMap<string, readonly string[]>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read a declared bot into the rule it matches and the labels it carries.
|
|
30
|
+
*
|
|
31
|
+
* A verified bot matches no rule, `CategoryAI` aside, which AWS applies to
|
|
32
|
+
* verified bots too. Either way the group labels the bot's category, its name
|
|
33
|
+
* and publisher where the declaration gives them, and whether it was verified.
|
|
34
|
+
*/
|
|
35
|
+
export declare function simWafBotDeclared(bot: SimWafBotDeclaration): SimWafBotDeclared;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SimWafDeclarationError } from "../error/sim-wafv2.error.js";
|
|
2
|
+
import { simWafBotCategories, simWafBotCategoryMatchingVerified, simWafBotControlRuleSet, } from "./group/sim-waf-bot-control.js";
|
|
3
|
+
/**
|
|
4
|
+
* Read a declared bot into the rule it matches and the labels it carries.
|
|
5
|
+
*
|
|
6
|
+
* A verified bot matches no rule, `CategoryAI` aside, which AWS applies to
|
|
7
|
+
* verified bots too. Either way the group labels the bot's category, its name
|
|
8
|
+
* and publisher where the declaration gives them, and whether it was verified.
|
|
9
|
+
*/
|
|
10
|
+
export function simWafBotDeclared(bot) {
|
|
11
|
+
const rule = requiredCategoryRule(bot.category);
|
|
12
|
+
const verified = bot.verified === true;
|
|
13
|
+
const matches = !verified || bot.category === simWafBotCategoryMatchingVerified;
|
|
14
|
+
return {
|
|
15
|
+
matches: matches ? [rule] : [],
|
|
16
|
+
groupLabels: new Map([
|
|
17
|
+
[
|
|
18
|
+
simWafBotControlRuleSet.name,
|
|
19
|
+
[
|
|
20
|
+
`bot:category:${bot.category}`,
|
|
21
|
+
...optionalLabel("bot:name", bot.name),
|
|
22
|
+
...optionalLabel("bot:organization", bot.organization),
|
|
23
|
+
verified ? "bot:verified" : "bot:unverified",
|
|
24
|
+
],
|
|
25
|
+
],
|
|
26
|
+
]),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The rule for one category, refusing a category Bot Control does not name.
|
|
31
|
+
*/
|
|
32
|
+
function requiredCategoryRule(category) {
|
|
33
|
+
const rule = simWafBotCategories.get(category);
|
|
34
|
+
if (rule === undefined) {
|
|
35
|
+
throw new SimWafDeclarationError(`Bot Control names no bot category ${category}. The categories are ` +
|
|
36
|
+
`${simWafBotCategories.keys().toArray().join(", ")}.`);
|
|
37
|
+
}
|
|
38
|
+
return rule;
|
|
39
|
+
}
|
|
40
|
+
function optionalLabel(prefix, value) {
|
|
41
|
+
return value === undefined ? [] : [`${prefix}:${value}`];
|
|
42
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type SimWafBotDeclaration } from "./sim-waf-bot-declaration.js";
|
|
2
|
+
/**
|
|
3
|
+
* The managed rules a test says claim a request.
|
|
4
|
+
*/
|
|
5
|
+
export interface SimWafManagedMatchDeclaration {
|
|
6
|
+
/** The rules that claim the request, by the name AWS gives them. */
|
|
7
|
+
readonly matches?: readonly string[] | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* The bot that sent the request, for Bot Control to match and label as it
|
|
10
|
+
* would have identified it.
|
|
11
|
+
*/
|
|
12
|
+
readonly bot?: SimWafBotDeclaration | undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* What a test declared about the requests to one URI path.
|
|
16
|
+
*/
|
|
17
|
+
export interface SimWafDeclared {
|
|
18
|
+
readonly matches: ReadonlySet<string>;
|
|
19
|
+
readonly groupLabels: ReadonlyMap<string, readonly string[]>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* What a request nothing was declared for carries.
|
|
23
|
+
*/
|
|
24
|
+
export declare const simWafNothingDeclared: SimWafDeclared;
|
|
25
|
+
/**
|
|
26
|
+
* Read a declaration into the rules that match and the labels groups add.
|
|
27
|
+
*
|
|
28
|
+
* `ruleNamed` checks a rule name the declaration gives, and answers with the
|
|
29
|
+
* name the rule goes by.
|
|
30
|
+
*/
|
|
31
|
+
export declare function simWafReadDeclaration(declaration: SimWafManagedMatchDeclaration, ruleNamed: (name: string) => string): SimWafDeclared;
|
|
32
|
+
/**
|
|
33
|
+
* The labels one group adds to a request whatever its rules decide.
|
|
34
|
+
*/
|
|
35
|
+
export declare function simWafDeclaredGroupLabels(declared: SimWafDeclared, groupName: string): readonly string[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { simWafBotDeclared, } from "./sim-waf-bot-declaration.js";
|
|
2
|
+
/**
|
|
3
|
+
* What a request nothing was declared for carries.
|
|
4
|
+
*/
|
|
5
|
+
export const simWafNothingDeclared = {
|
|
6
|
+
matches: new Set(),
|
|
7
|
+
groupLabels: new Map(),
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Read a declaration into the rules that match and the labels groups add.
|
|
11
|
+
*
|
|
12
|
+
* `ruleNamed` checks a rule name the declaration gives, and answers with the
|
|
13
|
+
* name the rule goes by.
|
|
14
|
+
*/
|
|
15
|
+
export function simWafReadDeclaration(declaration, ruleNamed) {
|
|
16
|
+
const bot = declaration.bot === undefined
|
|
17
|
+
? simWafNothingDeclared
|
|
18
|
+
: simWafBotDeclared(declaration.bot);
|
|
19
|
+
const named = (declaration.matches ?? []).map((name) => ruleNamed(name));
|
|
20
|
+
return {
|
|
21
|
+
matches: new Set([...named, ...bot.matches]),
|
|
22
|
+
groupLabels: bot.groupLabels,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The labels one group adds to a request whatever its rules decide.
|
|
27
|
+
*/
|
|
28
|
+
export function simWafDeclaredGroupLabels(declared, groupName) {
|
|
29
|
+
return declared.groupLabels.get(groupName) ?? [];
|
|
30
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SimWafManagedRuleGroupDefinition } from "./sim-waf-managed-rule.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Stop compiling a rule whose group configuration this simulation does not
|
|
4
|
+
* evaluate, so the web ACL holds it unevaluated.
|
|
5
|
+
*
|
|
6
|
+
* Bot Control at `COMMON` is evaluated, with or without the configuration
|
|
7
|
+
* that names the level. `TARGETED` is held, since its rules read tokens,
|
|
8
|
+
* browser signals and traffic across requests. Every other configuration sets
|
|
9
|
+
* up the account takeover and account creation groups, which are held too.
|
|
10
|
+
*/
|
|
11
|
+
export declare function refuseUnsimulatedSimWafGroupConfigs(configs: readonly unknown[] | undefined, group: SimWafManagedRuleGroupDefinition, ruleName: string): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { refuseSimWafRuleInput } from "../statement/sim-waf-rule-refusals.js";
|
|
2
|
+
import { simWafBotControlRuleSet } from "./group/sim-waf-bot-control.js";
|
|
3
|
+
/**
|
|
4
|
+
* Stop compiling a rule whose group configuration this simulation does not
|
|
5
|
+
* evaluate, so the web ACL holds it unevaluated.
|
|
6
|
+
*
|
|
7
|
+
* Bot Control at `COMMON` is evaluated, with or without the configuration
|
|
8
|
+
* that names the level. `TARGETED` is held, since its rules read tokens,
|
|
9
|
+
* browser signals and traffic across requests. Every other configuration sets
|
|
10
|
+
* up the account takeover and account creation groups, which are held too.
|
|
11
|
+
*/
|
|
12
|
+
export function refuseUnsimulatedSimWafGroupConfigs(configs, group, ruleName) {
|
|
13
|
+
const written = configs ?? [];
|
|
14
|
+
for (const config of written) {
|
|
15
|
+
const level = botControlLevel(config);
|
|
16
|
+
if (group !== simWafBotControlRuleSet || level === undefined) {
|
|
17
|
+
refuseSimWafRuleInput(ruleName, "the rule group member ManagedRuleGroupConfigs", "it configures the account takeover and account creation groups, " +
|
|
18
|
+
"and Bot Control's level, and an entry holding nothing but Bot " +
|
|
19
|
+
"Control at COMMON is the one configuration simulated");
|
|
20
|
+
}
|
|
21
|
+
if (level !== "COMMON") {
|
|
22
|
+
refuseSimWafRuleInput(ruleName, `Bot Control at the ${level} inspection level`, "the targeted rules read tokens, browser signals and traffic across " +
|
|
23
|
+
"requests, and COMMON is the level simulated");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The level one entry runs Bot Control at, when the entry is Bot Control's
|
|
29
|
+
* configuration and nothing else.
|
|
30
|
+
*
|
|
31
|
+
* Anything else answers with no level, so a malformed entry or one carrying
|
|
32
|
+
* another member beside Bot Control's is held rather than read as `COMMON`.
|
|
33
|
+
*/
|
|
34
|
+
function botControlLevel(config) {
|
|
35
|
+
const isBotControlAlone = typeof config === "object" &&
|
|
36
|
+
config !== null &&
|
|
37
|
+
Object.keys(config).join(",") === "AWSManagedRulesBotControlRuleSet";
|
|
38
|
+
return isBotControlAlone
|
|
39
|
+
? config.AWSManagedRulesBotControlRuleSet
|
|
40
|
+
?.InspectionLevel
|
|
41
|
+
: undefined;
|
|
42
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { SimWafManagedRuleGroupStatementInput, SimWafOverrideActionInput } from "./sim-waf-managed-group.type.js";
|
|
2
2
|
import type { SimWafManagedRuleGroupDefinition } from "./sim-waf-managed-rule.type.js";
|
|
3
3
|
/**
|
|
4
|
-
* Find the simulated group a statement names,
|
|
4
|
+
* Find the simulated group a statement names, stopping the rule's compilation
|
|
5
|
+
* at any other so the web ACL holds it unevaluated.
|
|
5
6
|
*
|
|
6
|
-
* The
|
|
7
|
+
* The reason names the groups that are simulated, because the ones that are
|
|
7
8
|
* not are left out for reasons a reader cannot guess from the name: a group
|
|
8
|
-
* that decides by
|
|
9
|
-
*
|
|
9
|
+
* that decides by behaviour across requests has one request to look at, and a
|
|
10
|
+
* group whose detection AWS does not describe cannot be reproduced at all.
|
|
10
11
|
*/
|
|
11
12
|
export declare function requiredSimWafManagedRuleGroup(statement: SimWafManagedRuleGroupStatementInput, ruleName: string): SimWafManagedRuleGroupDefinition;
|
|
12
13
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { invalidSimWafRule, refuseSimWafRuleInput, } from "../statement/sim-waf-rule-refusals.js";
|
|
2
2
|
import { findSimWafManagedRuleGroup, simWafManagedRuleGroupNames, } from "./sim-waf-managed-rule-groups.js";
|
|
3
|
+
import { refuseUnsimulatedSimWafGroupConfigs } from "./sim-waf-managed-group-configs.js";
|
|
3
4
|
/**
|
|
4
5
|
* The rule group statement members real WAFv2 takes and this simulation does
|
|
5
6
|
* not.
|
|
@@ -15,19 +16,15 @@ const refusedMembers = new Map([
|
|
|
15
16
|
"AWS replaced it with RuleActionOverrides, which says which action a " +
|
|
16
17
|
"named rule takes rather than only that it takes none",
|
|
17
18
|
],
|
|
18
|
-
[
|
|
19
|
-
"ManagedRuleGroupConfigs",
|
|
20
|
-
"it configures the Bot Control, account takeover and account creation " +
|
|
21
|
-
"groups, and none of those is simulated",
|
|
22
|
-
],
|
|
23
19
|
]);
|
|
24
20
|
/**
|
|
25
|
-
* Find the simulated group a statement names,
|
|
21
|
+
* Find the simulated group a statement names, stopping the rule's compilation
|
|
22
|
+
* at any other so the web ACL holds it unevaluated.
|
|
26
23
|
*
|
|
27
|
-
* The
|
|
24
|
+
* The reason names the groups that are simulated, because the ones that are
|
|
28
25
|
* not are left out for reasons a reader cannot guess from the name: a group
|
|
29
|
-
* that decides by
|
|
30
|
-
*
|
|
26
|
+
* that decides by behaviour across requests has one request to look at, and a
|
|
27
|
+
* group whose detection AWS does not describe cannot be reproduced at all.
|
|
31
28
|
*/
|
|
32
29
|
export function requiredSimWafManagedRuleGroup(statement, ruleName) {
|
|
33
30
|
for (const [member, value] of Object.entries(statement)) {
|
|
@@ -42,6 +39,7 @@ export function requiredSimWafManagedRuleGroup(statement, ruleName) {
|
|
|
42
39
|
const simulated = simWafManagedRuleGroupNames().join(", ");
|
|
43
40
|
refuseSimWafRuleInput(ruleName, `the managed rule group ${named}`, `the simulated groups are ${simulated}`);
|
|
44
41
|
}
|
|
42
|
+
refuseUnsimulatedSimWafGroupConfigs(statement.ManagedRuleGroupConfigs, group, ruleName);
|
|
45
43
|
return group;
|
|
46
44
|
}
|
|
47
45
|
/**
|