@kensio/yulin 1.21.23 → 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/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/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
|
@@ -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
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { compileSimWafStatement } from "../statement/sim-waf-statement.js";
|
|
2
|
-
import { SimWafAction } from "../web-acl/sim-waf-action.js";
|
|
3
2
|
import { requiredSimWafManagedRuleGroup, simWafGroupCountsEverything, } from "./sim-waf-managed-group-input.js";
|
|
3
|
+
import { simWafDeclaredGroupLabels } from "./sim-waf-managed-declaration.js";
|
|
4
|
+
import { simWafAddGroupLabels, simWafManagedRuleActions, } from "./sim-waf-managed-rule-actions.js";
|
|
4
5
|
import { simWafManagedRuleOverrides } from "./sim-waf-managed-rule-overrides.js";
|
|
5
6
|
import { simWafManagedRequestParts } from "./sim-waf-managed-request.js";
|
|
6
7
|
/**
|
|
@@ -20,8 +21,11 @@ import { simWafManagedRequestParts } from "./sim-waf-managed-request.js";
|
|
|
20
21
|
export function compileSimWafManagedRuleGroup(properties) {
|
|
21
22
|
const { statement, ruleName, scope } = properties;
|
|
22
23
|
const group = requiredSimWafManagedRuleGroup(statement, ruleName);
|
|
23
|
-
const
|
|
24
|
-
|
|
24
|
+
const actions = simWafManagedRuleActions({
|
|
25
|
+
ruleName,
|
|
26
|
+
overrides: simWafManagedRuleOverrides(statement, group, ruleName, scope.customResponseBodies),
|
|
27
|
+
counting: simWafGroupCountsEverything(properties.overrideAction, ruleName),
|
|
28
|
+
});
|
|
25
29
|
const scopeDown = statement.ScopeDownStatement === undefined
|
|
26
30
|
? undefined
|
|
27
31
|
: compileSimWafStatement(statement.ScopeDownStatement, {
|
|
@@ -29,10 +33,6 @@ export function compileSimWafManagedRuleGroup(properties) {
|
|
|
29
33
|
clock: scope.clock,
|
|
30
34
|
ruleName,
|
|
31
35
|
});
|
|
32
|
-
// Every rule in the three simulated groups blocks by default, and a group
|
|
33
|
-
// that is counting counts whatever the rule that matched was set to.
|
|
34
|
-
const blocking = SimWafAction.read({ Block: {} }, ruleName, {});
|
|
35
|
-
const counted = SimWafAction.read({ Count: {} }, ruleName, {});
|
|
36
36
|
const { managedRules } = scope;
|
|
37
37
|
return (request) => {
|
|
38
38
|
// A scope-down statement decides whether the group sees the request at
|
|
@@ -41,21 +41,23 @@ export function compileSimWafManagedRuleGroup(properties) {
|
|
|
41
41
|
return undefined;
|
|
42
42
|
}
|
|
43
43
|
const parts = simWafManagedRequestParts(request);
|
|
44
|
-
const declared = managedRules.
|
|
44
|
+
const declared = managedRules.declared(request);
|
|
45
45
|
let matched = false;
|
|
46
|
+
simWafAddGroupLabels(request, group, simWafDeclaredGroupLabels(declared, group.name));
|
|
46
47
|
for (const rule of group.rules) {
|
|
47
|
-
if (!declared.has(rule.name) && rule.detects?.(parts) !== true) {
|
|
48
|
+
if (!declared.matches.has(rule.name) && rule.detects?.(parts) !== true) {
|
|
48
49
|
continue;
|
|
49
50
|
}
|
|
50
|
-
request
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
simWafAddGroupLabels(request, group, [
|
|
52
|
+
rule.label,
|
|
53
|
+
...(rule.labels ?? []),
|
|
54
|
+
]);
|
|
55
|
+
const action = actions.of(rule);
|
|
54
56
|
if (action.isTerminating) {
|
|
55
57
|
return action;
|
|
56
58
|
}
|
|
57
59
|
matched = true;
|
|
58
60
|
}
|
|
59
|
-
return matched ? counted : undefined;
|
|
61
|
+
return matched ? actions.counted : undefined;
|
|
60
62
|
};
|
|
61
63
|
}
|
|
@@ -3,8 +3,8 @@ import type { SimWafActionInput } from "../web-acl/sim-waf-action.type.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Minimal structural WAFv2 ManagedRuleGroupStatement.
|
|
5
5
|
*
|
|
6
|
-
* The members Yulin
|
|
7
|
-
* statement
|
|
6
|
+
* The members Yulin does not simulate are declared here rather than left out,
|
|
7
|
+
* so a rule whose statement names one is held and reported by name.
|
|
8
8
|
*
|
|
9
9
|
* https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/wafv2/Interface/ManagedRuleGroupStatement/
|
|
10
10
|
*/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SimWafInspectedRequest } from "../evaluate/sim-waf-inspected-request.js";
|
|
2
|
+
import { SimWafAction } from "../web-acl/sim-waf-action.js";
|
|
3
|
+
import type { SimWafManagedRuleDefinition, SimWafManagedRuleGroupDefinition } from "./sim-waf-managed-rule.type.js";
|
|
4
|
+
interface SimWafManagedRuleActionsProperties {
|
|
5
|
+
readonly ruleName: string;
|
|
6
|
+
readonly overrides: ReadonlyMap<string, SimWafAction>;
|
|
7
|
+
readonly counting: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* What each rule of one managed rule group does to a request it claims.
|
|
11
|
+
*/
|
|
12
|
+
export interface SimWafManagedRuleActions {
|
|
13
|
+
/** The action one rule of the group takes. */
|
|
14
|
+
of(rule: SimWafManagedRuleDefinition): SimWafAction;
|
|
15
|
+
/** The action a group answers with when its rules only counted. */
|
|
16
|
+
readonly counted: SimWafAction;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Settle what the rules of a group do, where the rule naming it is compiled.
|
|
20
|
+
*
|
|
21
|
+
* A rule takes its own default (`Block`, or `Count` for the few AWS ships
|
|
22
|
+
* counting), an action override replaces that, and a group counting as a
|
|
23
|
+
* whole counts whatever its rules were set to.
|
|
24
|
+
*/
|
|
25
|
+
export declare function simWafManagedRuleActions(properties: SimWafManagedRuleActionsProperties): SimWafManagedRuleActions;
|
|
26
|
+
/**
|
|
27
|
+
* Add labels to a request within a group's namespace.
|
|
28
|
+
*/
|
|
29
|
+
export declare function simWafAddGroupLabels(request: SimWafInspectedRequest, group: SimWafManagedRuleGroupDefinition, labels: readonly string[]): void;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SimWafAction } from "../web-acl/sim-waf-action.js";
|
|
2
|
+
/**
|
|
3
|
+
* Settle what the rules of a group do, where the rule naming it is compiled.
|
|
4
|
+
*
|
|
5
|
+
* A rule takes its own default (`Block`, or `Count` for the few AWS ships
|
|
6
|
+
* counting), an action override replaces that, and a group counting as a
|
|
7
|
+
* whole counts whatever its rules were set to.
|
|
8
|
+
*/
|
|
9
|
+
export function simWafManagedRuleActions(properties) {
|
|
10
|
+
const { ruleName, overrides, counting } = properties;
|
|
11
|
+
const blocking = SimWafAction.read({ Block: {} }, ruleName, {});
|
|
12
|
+
const counted = SimWafAction.read({ Count: {} }, ruleName, {});
|
|
13
|
+
const ownAction = (rule) => rule.counts === true ? counted : blocking;
|
|
14
|
+
return {
|
|
15
|
+
of: (rule) => counting ? counted : (overrides.get(rule.name) ?? ownAction(rule)),
|
|
16
|
+
counted,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Add labels to a request within a group's namespace.
|
|
21
|
+
*/
|
|
22
|
+
export function simWafAddGroupLabels(request, group, labels) {
|
|
23
|
+
for (const label of labels) {
|
|
24
|
+
request.labels.add(`${group.labelNamespace}:${label}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -2,8 +2,9 @@ import type { SimWafManagedRuleDefinition, SimWafManagedRuleGroupDefinition } fr
|
|
|
2
2
|
/**
|
|
3
3
|
* The vendor the simulated managed rule groups belong to.
|
|
4
4
|
*
|
|
5
|
-
* A group from any other vendor is
|
|
6
|
-
* subscription buys rules nobody outside the
|
|
5
|
+
* A rule naming a group from any other vendor is held unevaluated,
|
|
6
|
+
* marketplace groups included: a subscription buys rules nobody outside the
|
|
7
|
+
* vendor has ever seen.
|
|
7
8
|
*/
|
|
8
9
|
export declare const simWafManagedVendorName = "AWS";
|
|
9
10
|
/**
|
|
@@ -18,7 +19,8 @@ export interface SimWafManagedRuleEntry {
|
|
|
18
19
|
*/
|
|
19
20
|
export declare function findSimWafManagedRuleGroup(vendorName: string | undefined, name: string | undefined): SimWafManagedRuleGroupDefinition | undefined;
|
|
20
21
|
/**
|
|
21
|
-
* The groups that are simulated, named as
|
|
22
|
+
* The groups that are simulated, named as an unsimulated group's reason names
|
|
23
|
+
* them.
|
|
22
24
|
*/
|
|
23
25
|
export declare function simWafManagedRuleGroupNames(): readonly string[];
|
|
24
26
|
/**
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { simWafAdminProtectionRuleSet } from "./group/sim-waf-admin-protection.js";
|
|
2
|
+
import { simWafBotControlRuleSet } from "./group/sim-waf-bot-control.js";
|
|
2
3
|
import { simWafCommonRuleSet } from "./group/sim-waf-common-rule-set.js";
|
|
4
|
+
import { simWafAnonymousIpList, simWafIpReputationList, } from "./group/sim-waf-ip-reputation.js";
|
|
3
5
|
import { simWafKnownBadInputsRuleSet } from "./group/sim-waf-known-bad-inputs.js";
|
|
4
6
|
/**
|
|
5
7
|
* The vendor the simulated managed rule groups belong to.
|
|
6
8
|
*
|
|
7
|
-
* A group from any other vendor is
|
|
8
|
-
* subscription buys rules nobody outside the
|
|
9
|
+
* A rule naming a group from any other vendor is held unevaluated,
|
|
10
|
+
* marketplace groups included: a subscription buys rules nobody outside the
|
|
11
|
+
* vendor has ever seen.
|
|
9
12
|
*/
|
|
10
13
|
export const simWafManagedVendorName = "AWS";
|
|
11
14
|
const groups = [
|
|
12
15
|
simWafCommonRuleSet,
|
|
13
16
|
simWafKnownBadInputsRuleSet,
|
|
14
17
|
simWafAdminProtectionRuleSet,
|
|
18
|
+
simWafIpReputationList,
|
|
19
|
+
simWafAnonymousIpList,
|
|
20
|
+
simWafBotControlRuleSet,
|
|
15
21
|
];
|
|
16
22
|
const byName = new Map(groups.map((group) => [group.name, group]));
|
|
17
23
|
const rulesByName = new Map(groups.flatMap((group) => group.rules.map((rule) => [rule.name, { group, rule }])));
|
|
@@ -24,7 +30,8 @@ export function findSimWafManagedRuleGroup(vendorName, name) {
|
|
|
24
30
|
: undefined;
|
|
25
31
|
}
|
|
26
32
|
/**
|
|
27
|
-
* The groups that are simulated, named as
|
|
33
|
+
* The groups that are simulated, named as an unsimulated group's reason names
|
|
34
|
+
* them.
|
|
28
35
|
*/
|
|
29
36
|
export function simWafManagedRuleGroupNames() {
|
|
30
37
|
return groups.map((group) => group.name);
|
|
@@ -23,14 +23,23 @@ export type SimWafManagedDetector = (parts: SimWafManagedRequestParts) => boolea
|
|
|
23
23
|
/**
|
|
24
24
|
* One rule of an AWS managed rule group.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* A rule blocks by default unless it says it counts. A rule with no detector
|
|
27
|
+
* is a declared-only rule.
|
|
28
28
|
*/
|
|
29
29
|
export interface SimWafManagedRuleDefinition {
|
|
30
30
|
/** The rule name, as AWS names it and as an override names it. */
|
|
31
31
|
readonly name: string;
|
|
32
32
|
/** The label this rule adds, within its group's namespace. */
|
|
33
33
|
readonly label: string;
|
|
34
|
+
/**
|
|
35
|
+
* The labels the rule adds beside its own, within its group's namespace.
|
|
36
|
+
*
|
|
37
|
+
* A Bot Control rule labels the bot category or the signal it found as well
|
|
38
|
+
* as itself.
|
|
39
|
+
*/
|
|
40
|
+
readonly labels?: readonly string[] | undefined;
|
|
41
|
+
/** Whether the rule counts by default where most rules block. */
|
|
42
|
+
readonly counts?: boolean | undefined;
|
|
34
43
|
readonly tier: SimWafManagedRuleTier;
|
|
35
44
|
readonly detects?: SimWafManagedDetector | undefined;
|
|
36
45
|
}
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import type { SimWafInspectedRequest } from "../evaluate/sim-waf-inspected-request.js";
|
|
2
2
|
import { type SimWafManagedRuleReport } from "./sim-waf-managed-rule-report.js";
|
|
3
3
|
import type { SimWafManagedRuleTier } from "./sim-waf-managed-rule.type.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*/
|
|
7
|
-
export interface SimWafManagedMatchDeclaration {
|
|
8
|
-
/** The rules that claim the request, by the name AWS gives them. */
|
|
9
|
-
readonly matches: readonly string[];
|
|
10
|
-
}
|
|
4
|
+
import { type SimWafDeclared, type SimWafManagedMatchDeclaration } from "./sim-waf-managed-declaration.js";
|
|
5
|
+
export type { SimWafDeclared, SimWafManagedMatchDeclaration, } from "./sim-waf-managed-declaration.js";
|
|
11
6
|
/**
|
|
12
7
|
* The managed rule matches this simulated WAFv2 answers with, and what it
|
|
13
8
|
* covers of each rule.
|
|
@@ -24,6 +19,15 @@ export interface SimWafManagedMatchDeclaration {
|
|
|
24
19
|
* });
|
|
25
20
|
* ```
|
|
26
21
|
*
|
|
22
|
+
* Bot Control is declared by the bot rather than the rule, since a verified
|
|
23
|
+
* bot is labelled and matches no rule:
|
|
24
|
+
*
|
|
25
|
+
* ```typescript
|
|
26
|
+
* simAws.wafV2().managedRules().onRequest("/search", {
|
|
27
|
+
* bot: { category: "search_engine", name: "googlebot", verified: true },
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
27
31
|
* A declared match is a match, and everything after it is what the group would
|
|
28
32
|
* have done anyway: the rule adds its label, an action override applies to it,
|
|
29
33
|
* and the group blocks by that rule.
|
|
@@ -39,9 +43,10 @@ export declare class SimWafManagedRules {
|
|
|
39
43
|
*/
|
|
40
44
|
onRequest(uriPath: string, declaration: SimWafManagedMatchDeclaration): void;
|
|
41
45
|
/**
|
|
42
|
-
*
|
|
46
|
+
* What a test declared about one request: the rules that claim it, and the
|
|
47
|
+
* labels a group adds to it whatever its rules decide.
|
|
43
48
|
*/
|
|
44
|
-
|
|
49
|
+
declared(request: SimWafInspectedRequest): SimWafDeclared;
|
|
45
50
|
/**
|
|
46
51
|
* What this simulation covers of one managed rule.
|
|
47
52
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SimWafDeclarationError } from "../error/sim-wafv2.error.js";
|
|
2
2
|
import { findSimWafManagedRule, } from "./sim-waf-managed-rule-groups.js";
|
|
3
3
|
import { simWafManagedRuleReports, } from "./sim-waf-managed-rule-report.js";
|
|
4
|
-
|
|
4
|
+
import { simWafNothingDeclared, simWafReadDeclaration, } from "./sim-waf-managed-declaration.js";
|
|
5
5
|
/**
|
|
6
6
|
* The managed rule matches this simulated WAFv2 answers with, and what it
|
|
7
7
|
* covers of each rule.
|
|
@@ -18,6 +18,15 @@ const noMatches = new Set();
|
|
|
18
18
|
* });
|
|
19
19
|
* ```
|
|
20
20
|
*
|
|
21
|
+
* Bot Control is declared by the bot rather than the rule, since a verified
|
|
22
|
+
* bot is labelled and matches no rule:
|
|
23
|
+
*
|
|
24
|
+
* ```typescript
|
|
25
|
+
* simAws.wafV2().managedRules().onRequest("/search", {
|
|
26
|
+
* bot: { category: "search_engine", name: "googlebot", verified: true },
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
21
30
|
* A declared match is a match, and everything after it is what the group would
|
|
22
31
|
* have done anyway: the rule adds its label, an action override applies to it,
|
|
23
32
|
* and the group blocks by that rule.
|
|
@@ -36,13 +45,14 @@ export class SimWafManagedRules {
|
|
|
36
45
|
throw new SimWafDeclarationError("A declared managed rule match needs the URI path of the request it " +
|
|
37
46
|
"is declared for");
|
|
38
47
|
}
|
|
39
|
-
this.#byUriPath.set(uriPath,
|
|
48
|
+
this.#byUriPath.set(uriPath, simWafReadDeclaration(declaration, (name) => this.requiredRule(name).rule.name));
|
|
40
49
|
}
|
|
41
50
|
/**
|
|
42
|
-
*
|
|
51
|
+
* What a test declared about one request: the rules that claim it, and the
|
|
52
|
+
* labels a group adds to it whatever its rules decide.
|
|
43
53
|
*/
|
|
44
|
-
|
|
45
|
-
return this.#byUriPath.get(request.uriPath) ??
|
|
54
|
+
declared(request) {
|
|
55
|
+
return this.#byUriPath.get(request.uriPath) ?? simWafNothingDeclared;
|
|
46
56
|
}
|
|
47
57
|
/**
|
|
48
58
|
* What this simulation covers of one managed rule.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SimAwsAccountRegionScope } from "../../aws/sim-aws-account-region-scope.js";
|
|
2
2
|
import { type SimWafResourceKind } from "../sim-wafv2-arn.js";
|
|
3
3
|
import type { SimWafScope } from "../scope/sim-waf-scope.js";
|
|
4
|
+
import { type SimWafUnsimulatedPart } from "./sim-waf-unsimulated-part.js";
|
|
4
5
|
/**
|
|
5
6
|
* What every WAFv2 resource reports about itself in a listing.
|
|
6
7
|
*/
|
|
@@ -16,6 +17,7 @@ export interface SimWafResourceProperties {
|
|
|
16
17
|
readonly scope: SimWafScope;
|
|
17
18
|
readonly accountRegionScope: SimAwsAccountRegionScope;
|
|
18
19
|
readonly description?: string | undefined;
|
|
20
|
+
readonly tags?: readonly unknown[] | undefined;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* What a web ACL, an IP set and a regex pattern set have in common.
|
|
@@ -32,11 +34,19 @@ export declare abstract class SimWafResource {
|
|
|
32
34
|
readonly scope: SimWafScope;
|
|
33
35
|
readonly id: string;
|
|
34
36
|
readonly arn: string;
|
|
37
|
+
/** The tags the resource was created with, held as they were written. */
|
|
38
|
+
readonly tags: readonly unknown[];
|
|
35
39
|
protected constructor(kind: SimWafResourceKind, properties: SimWafResourceProperties);
|
|
36
40
|
/**
|
|
37
41
|
* What the resource was created or last updated with as its description.
|
|
38
42
|
*/
|
|
39
43
|
get description(): string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* What this resource was written with and the simulation does not act on.
|
|
46
|
+
*
|
|
47
|
+
* A web ACL adds the rules and members it holds without evaluating.
|
|
48
|
+
*/
|
|
49
|
+
get unsimulated(): readonly SimWafUnsimulatedPart[];
|
|
40
50
|
/**
|
|
41
51
|
* The token the next write to this resource has to present.
|
|
42
52
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { SimWafOptimisticLockException } from "../error/sim-wafv2.error.js";
|
|
3
3
|
import { simWafArn } from "../sim-wafv2-arn.js";
|
|
4
|
+
import { simWafTagsParts, } from "./sim-waf-unsimulated-part.js";
|
|
4
5
|
/**
|
|
5
6
|
* What a web ACL, an IP set and a regex pattern set have in common.
|
|
6
7
|
*
|
|
@@ -15,12 +16,15 @@ export class SimWafResource {
|
|
|
15
16
|
scope;
|
|
16
17
|
id = randomUUID();
|
|
17
18
|
arn;
|
|
19
|
+
/** The tags the resource was created with, held as they were written. */
|
|
20
|
+
tags;
|
|
18
21
|
#description;
|
|
19
22
|
#lockToken = randomUUID();
|
|
20
23
|
constructor(kind, properties) {
|
|
21
24
|
this.name = properties.name;
|
|
22
25
|
this.scope = properties.scope;
|
|
23
26
|
this.#description = properties.description;
|
|
27
|
+
this.tags = properties.tags ?? [];
|
|
24
28
|
this.arn = simWafArn({
|
|
25
29
|
accountRegionScope: properties.accountRegionScope,
|
|
26
30
|
scope: properties.scope,
|
|
@@ -35,6 +39,14 @@ export class SimWafResource {
|
|
|
35
39
|
get description() {
|
|
36
40
|
return this.#description;
|
|
37
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* What this resource was written with and the simulation does not act on.
|
|
44
|
+
*
|
|
45
|
+
* A web ACL adds the rules and members it holds without evaluating.
|
|
46
|
+
*/
|
|
47
|
+
get unsimulated() {
|
|
48
|
+
return simWafTagsParts(this.tags);
|
|
49
|
+
}
|
|
38
50
|
/**
|
|
39
51
|
* The token the next write to this resource has to present.
|
|
40
52
|
*/
|