@kensio/yulin 1.21.23 → 1.21.25
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/dynamodb/command/authorize/sim-dynamodb-authorizer.d.ts +19 -1
- package/dist/service/dynamodb/command/authorize/sim-dynamodb-authorizer.js +21 -3
- package/dist/service/dynamodb/command/authorize/sim-dynamodb-reached.d.ts +6 -3
- package/dist/service/dynamodb/command/query/sim-dynamodb-query.js +3 -1
- package/dist/service/dynamodb/command/scan/sim-dynamodb-scan.js +3 -1
- package/dist/service/dynamodb/command/table/sim-dynamodb-table-reach.d.ts +4 -0
- package/dist/service/dynamodb/command/table/sim-dynamodb-table-reach.js +1 -0
- package/dist/service/dynamodb/table/sim-dynamodb-table-arn.d.ts +13 -0
- package/dist/service/dynamodb/table/sim-dynamodb-table-arn.js +20 -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/dynamodb/README.md +26 -0
- package/docs/services/wafv2/README.md +243 -51
- package/package.json +3 -3
- 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
|
@@ -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
|
*/
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One part of a WAFv2 write this simulation holds and does not act on.
|
|
3
|
+
*
|
|
4
|
+
* A write carrying something Yulin does not simulate is accepted, and the read
|
|
5
|
+
* that follows returns it as written. What the simulation leaves out is
|
|
6
|
+
* reported here instead, so a test can find out how far the resource it wrote
|
|
7
|
+
* is from the one AWS would run.
|
|
8
|
+
*/
|
|
9
|
+
export interface SimWafUnsimulatedPart {
|
|
10
|
+
/**
|
|
11
|
+
* Where the part sits in what was written.
|
|
12
|
+
*
|
|
13
|
+
* A rule is `Rules.<rule name>`, a web ACL member is its own name, and a body
|
|
14
|
+
* inspection limit is `AssociationConfig.RequestBody.<resource type>`. These
|
|
15
|
+
* are the names a CloudFormation Resource records them under.
|
|
16
|
+
*/
|
|
17
|
+
readonly part: string;
|
|
18
|
+
/** Why the simulation does not act on it. */
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* What a resource's tags leave out, which is nothing when it has none.
|
|
23
|
+
*/
|
|
24
|
+
export declare function simWafTagsParts(tags: readonly unknown[]): readonly SimWafUnsimulatedPart[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const tagsReason = "the tags are held and nothing reads them, since ListTagsForResource is " +
|
|
2
|
+
"not simulated";
|
|
3
|
+
/**
|
|
4
|
+
* What a resource's tags leave out, which is nothing when it has none.
|
|
5
|
+
*/
|
|
6
|
+
export function simWafTagsParts(tags) {
|
|
7
|
+
return tags.length === 0 ? [] : [{ part: "Tags", reason: tagsReason }];
|
|
8
|
+
}
|
|
@@ -8,12 +8,11 @@ import type { SimWafIpSet } from "./ip-set/sim-waf-ip-set.js";
|
|
|
8
8
|
import type { SimWafManagedRules } from "./managed/sim-waf-managed-rules.js";
|
|
9
9
|
import type { SimWafRegexPatternSet } from "./regex-pattern-set/sim-waf-regex-pattern-set.js";
|
|
10
10
|
import type { SimWafScope } from "./scope/sim-waf-scope.js";
|
|
11
|
+
import type { SimWafUnsimulatedPart } from "./resource/sim-waf-unsimulated-part.js";
|
|
11
12
|
import { type SimWafV2Properties } from "./sim-wafv2-commands.js";
|
|
12
13
|
import { SimWafCfnResourceFactory } from "./cfn/sim-waf-cfn-resource-factory.js";
|
|
13
14
|
import { SimWafSets } from "./sim-wafv2-sets.js";
|
|
14
15
|
import type { SimWafWebAcl } from "./web-acl/sim-waf-web-acl.js";
|
|
15
|
-
import { type SimWafUnevaluatableRule } from "./web-acl/sim-waf-unevaluatable-rules.js";
|
|
16
|
-
import type { SimWafWebAclWriteInput } from "./command/web-acl/web-acl.command.js";
|
|
17
16
|
export type { SimWafEvaluationRequest } from "./evaluate/sim-waf-evaluation-request.js";
|
|
18
17
|
/**
|
|
19
18
|
* Simulated AWS WAFv2. Handles SDK commands. Emulates AWS behaviour and state.
|
|
@@ -71,6 +70,13 @@ export declare class SimWafV2 extends SimWafSets {
|
|
|
71
70
|
* compiled against, since a reference carries the ARN and nothing else.
|
|
72
71
|
*/
|
|
73
72
|
findRegexPatternSetByArn(regexPatternSetArn: string): SimWafRegexPatternSet | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* What a web ACL holds and this simulation does not act on, each part with
|
|
75
|
+
* its reason: a rule that claims no request (`Rules.<rule name>`), a member
|
|
76
|
+
* such as `CaptchaConfig`, a body inspection limit, the tags, and an
|
|
77
|
+
* association nothing is evaluated through (`Association.<resource ARN>`).
|
|
78
|
+
*/
|
|
79
|
+
unsimulatedParts(webAclArn: string): readonly SimWafUnsimulatedPart[];
|
|
74
80
|
/**
|
|
75
81
|
* Evaluate one HTTP request against a web ACL's rules.
|
|
76
82
|
*
|
|
@@ -89,16 +95,6 @@ export declare class SimWafV2 extends SimWafSets {
|
|
|
89
95
|
* nothing here, and `rules()` reports what is covered of each.
|
|
90
96
|
*/
|
|
91
97
|
managedRules(): SimWafManagedRules;
|
|
92
|
-
/**
|
|
93
|
-
* The rules of a web ACL input this simulation cannot evaluate.
|
|
94
|
-
*
|
|
95
|
-
* The simulator's own accessor rather than a WAFv2 operation. `CreateWebACL`
|
|
96
|
-
* refuses a web ACL carrying such a rule, because a web ACL that accepted
|
|
97
|
-
* one would allow a request AWS blocks. A template is deployed rule by rule
|
|
98
|
-
* instead, so the CloudFormation layer asks this first and leaves the rules
|
|
99
|
-
* it names out of the web ACL it writes.
|
|
100
|
-
*/
|
|
101
|
-
unevaluatableWebAclRules(input: SimWafWebAclWriteInput): readonly SimWafUnevaluatableRule[];
|
|
102
98
|
/**
|
|
103
99
|
* Handle a CreateWebACL Command from the SDK.
|
|
104
100
|
*/
|
|
@@ -147,4 +143,8 @@ export declare class SimWafV2 extends SimWafSets {
|
|
|
147
143
|
* Get this service's SDK Command router for SDK client interception.
|
|
148
144
|
*/
|
|
149
145
|
sdkCommandRouter(): SimSdkCommandRouter;
|
|
146
|
+
/**
|
|
147
|
+
* Find a web ACL by its ARN, refusing one that is not here.
|
|
148
|
+
*/
|
|
149
|
+
private requireWebAcl;
|
|
150
150
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { SimCreateWebAclCommandInput, SimWafSummaryOutput } from "./command/web-acl/web-acl.command.js";
|
|
1
|
+
import type { SimCreateWebAclCommandInput, SimWafSummaryOutput, SimWafWebAclOutput } from "./command/web-acl/web-acl.command.js";
|
|
2
2
|
import type { SimWafDecision } from "./evaluate/sim-waf-decision.js";
|
|
3
|
+
import type { SimWafUnsimulatedPart } from "./resource/sim-waf-unsimulated-part.js";
|
|
3
4
|
import type { SimWafStatementInput } from "./statement/sim-waf-statement.type.js";
|
|
4
5
|
import type { SimWafRuleInput } from "./web-acl/sim-waf-rule.type.js";
|
|
5
6
|
import type { SimWafV2 } from "./sim-wafv2.js";
|
|
@@ -47,3 +48,20 @@ export declare function simWafWebAclDecisions(simWaf: SimWafV2, rules: readonly
|
|
|
47
48
|
* makes its requests with this.
|
|
48
49
|
*/
|
|
49
50
|
export declare function simWafBrowserRequest(url: string, init?: RequestInit): Request;
|
|
51
|
+
/**
|
|
52
|
+
* A web ACL as GetWebACL reads it back, what the simulation says it left out
|
|
53
|
+
* of it, and what it decided about an ordinary request.
|
|
54
|
+
*/
|
|
55
|
+
export interface SimWafHeld {
|
|
56
|
+
readonly webAcl: SimWafWebAclOutput;
|
|
57
|
+
readonly parts: readonly SimWafUnsimulatedPart[];
|
|
58
|
+
readonly blocked: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create a web ACL, read it back, and put one request through it.
|
|
62
|
+
*/
|
|
63
|
+
export declare function simWafHeldWebAcl(simWaf: SimWafV2, webAcl: Partial<SimCreateWebAclCommandInput>): Promise<SimWafHeld>;
|
|
64
|
+
/**
|
|
65
|
+
* The reason the simulation gives for leaving out one part.
|
|
66
|
+
*/
|
|
67
|
+
export declare function simWafUnsimulatedReason(parts: readonly SimWafUnsimulatedPart[], part: string): string;
|
|
@@ -60,3 +60,32 @@ export function simWafBrowserRequest(url, init = {}) {
|
|
|
60
60
|
return new Request(url, { ...init, headers });
|
|
61
61
|
}
|
|
62
62
|
const browserUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36";
|
|
63
|
+
/**
|
|
64
|
+
* Create a web ACL, read it back, and put one request through it.
|
|
65
|
+
*/
|
|
66
|
+
export async function simWafHeldWebAcl(simWaf, webAcl) {
|
|
67
|
+
const created = await createSimWafWebAcl(simWaf, {
|
|
68
|
+
...simWafCreateWebAclFactory.make(),
|
|
69
|
+
...webAcl,
|
|
70
|
+
});
|
|
71
|
+
const read = await simWaf.getWebAcl({
|
|
72
|
+
input: { Name: created.Name, Scope: "REGIONAL", Id: created.Id },
|
|
73
|
+
});
|
|
74
|
+
assertDefined(read.WebACL, "Simulated WAFv2 read back no web ACL");
|
|
75
|
+
return {
|
|
76
|
+
webAcl: read.WebACL,
|
|
77
|
+
parts: simWaf.unsimulatedParts(created.ARN),
|
|
78
|
+
blocked: simWaf.evaluateRequest({
|
|
79
|
+
webAclArn: created.ARN,
|
|
80
|
+
request: new Request("https://example.com/search"),
|
|
81
|
+
}).action === "BLOCK",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The reason the simulation gives for leaving out one part.
|
|
86
|
+
*/
|
|
87
|
+
export function simWafUnsimulatedReason(parts, part) {
|
|
88
|
+
const found = parts.find((candidate) => candidate.part === part);
|
|
89
|
+
assertDefined(found, `Simulated WAFv2 reported no unsimulated part ${part}`);
|
|
90
|
+
return found.reason;
|
|
91
|
+
}
|
|
@@ -4,7 +4,6 @@ import { SimWafSdkCommandRouter } from "./sdk/sim-wafv2-sdk-command-router.js";
|
|
|
4
4
|
import { SimWafCommands, } from "./sim-wafv2-commands.js";
|
|
5
5
|
import { SimWafCfnResourceFactory } from "./cfn/sim-waf-cfn-resource-factory.js";
|
|
6
6
|
import { SimWafSets } from "./sim-wafv2-sets.js";
|
|
7
|
-
import { unevaluatableSimWafRules, } from "./web-acl/sim-waf-unevaluatable-rules.js";
|
|
8
7
|
/**
|
|
9
8
|
* Simulated AWS WAFv2. Handles SDK commands. Emulates AWS behaviour and state.
|
|
10
9
|
*
|
|
@@ -74,6 +73,19 @@ export class SimWafV2 extends SimWafSets {
|
|
|
74
73
|
findRegexPatternSetByArn(regexPatternSetArn) {
|
|
75
74
|
return this.commands.regexPatternSets.findByArn(regexPatternSetArn);
|
|
76
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* What a web ACL holds and this simulation does not act on, each part with
|
|
78
|
+
* its reason: a rule that claims no request (`Rules.<rule name>`), a member
|
|
79
|
+
* such as `CaptchaConfig`, a body inspection limit, the tags, and an
|
|
80
|
+
* association nothing is evaluated through (`Association.<resource ARN>`).
|
|
81
|
+
*/
|
|
82
|
+
unsimulatedParts(webAclArn) {
|
|
83
|
+
const webAcl = this.requireWebAcl(webAclArn);
|
|
84
|
+
return [
|
|
85
|
+
...webAcl.unsimulated,
|
|
86
|
+
...this.commands.associations.unsimulatedFor(webAcl),
|
|
87
|
+
];
|
|
88
|
+
}
|
|
77
89
|
/**
|
|
78
90
|
* Evaluate one HTTP request against a web ACL's rules.
|
|
79
91
|
*
|
|
@@ -84,11 +96,7 @@ export class SimWafV2 extends SimWafSets {
|
|
|
84
96
|
* front of.
|
|
85
97
|
*/
|
|
86
98
|
evaluateRequest(evaluation) {
|
|
87
|
-
const webAcl = this.
|
|
88
|
-
if (webAcl === undefined) {
|
|
89
|
-
throw new SimWafNonexistentItemException(`AWS WAF couldn't perform the operation because your resource ` +
|
|
90
|
-
`doesn't exist: web ACL ${evaluation.webAclArn}.`);
|
|
91
|
-
}
|
|
99
|
+
const webAcl = this.requireWebAcl(evaluation.webAclArn);
|
|
92
100
|
const limitBytes = webAcl.bodyInspectionLimitBytes(evaluation.resourceType);
|
|
93
101
|
return webAcl.evaluate(simWafInspectedRequest(evaluation.request, evaluation.body, limitBytes));
|
|
94
102
|
}
|
|
@@ -102,23 +110,6 @@ export class SimWafV2 extends SimWafSets {
|
|
|
102
110
|
managedRules() {
|
|
103
111
|
return this.commands.managedRules;
|
|
104
112
|
}
|
|
105
|
-
/**
|
|
106
|
-
* The rules of a web ACL input this simulation cannot evaluate.
|
|
107
|
-
*
|
|
108
|
-
* The simulator's own accessor rather than a WAFv2 operation. `CreateWebACL`
|
|
109
|
-
* refuses a web ACL carrying such a rule, because a web ACL that accepted
|
|
110
|
-
* one would allow a request AWS blocks. A template is deployed rule by rule
|
|
111
|
-
* instead, so the CloudFormation layer asks this first and leaves the rules
|
|
112
|
-
* it names out of the web ACL it writes.
|
|
113
|
-
*/
|
|
114
|
-
unevaluatableWebAclRules(input) {
|
|
115
|
-
return unevaluatableSimWafRules(input.Rules, {
|
|
116
|
-
regexPatternSets: this.commands.regexPatternSets,
|
|
117
|
-
managedRules: this.commands.managedRules,
|
|
118
|
-
clock: this.commands.background,
|
|
119
|
-
customResponseBodies: input.CustomResponseBodies ?? {},
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
113
|
/**
|
|
123
114
|
* Handle a CreateWebACL Command from the SDK.
|
|
124
115
|
*/
|
|
@@ -201,4 +192,15 @@ export class SimWafV2 extends SimWafSets {
|
|
|
201
192
|
sdkCommandRouter() {
|
|
202
193
|
return this.#sdkRouter;
|
|
203
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Find a web ACL by its ARN, refusing one that is not here.
|
|
197
|
+
*/
|
|
198
|
+
requireWebAcl(webAclArn) {
|
|
199
|
+
const webAcl = this.findWebAclByArn(webAclArn);
|
|
200
|
+
if (webAcl === undefined) {
|
|
201
|
+
throw new SimWafNonexistentItemException(`AWS WAF couldn't perform the operation because your resource ` +
|
|
202
|
+
`doesn't exist: web ACL ${webAclArn}.`);
|
|
203
|
+
}
|
|
204
|
+
return webAcl;
|
|
205
|
+
}
|
|
204
206
|
}
|
|
@@ -4,8 +4,8 @@ import type { SimWafMatchPatternInput } from "./sim-waf-match-pattern.js";
|
|
|
4
4
|
* shape.
|
|
5
5
|
*
|
|
6
6
|
* The members Yulin does not simulate are declared here rather than left out,
|
|
7
|
-
* so a rule that names one is
|
|
8
|
-
* with no field at all.
|
|
7
|
+
* so a rule that names one is held and reported by name instead of being read
|
|
8
|
+
* as a rule with no field at all.
|
|
9
9
|
*/
|
|
10
10
|
export interface SimWafFieldToMatchInput {
|
|
11
11
|
readonly UriPath?: unknown;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Stop compiling a rule at something real WAFv2 takes and this simulation does
|
|
3
3
|
* not.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* `SimWafRule.compile` catches it and holds the rule unevaluated, with this
|
|
6
|
+
* message as the reason the web ACL reports. The message names the rule and
|
|
7
|
+
* what in it was left out, because a web ACL is a list of rules that all look
|
|
8
|
+
* alike from the outside and the name is the only thing that says which one to
|
|
9
|
+
* go and look at.
|
|
8
10
|
*/
|
|
9
11
|
export declare function refuseSimWafRuleInput(ruleName: string, refused: string, reason: string): never;
|
|
10
12
|
/**
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { SimWafInvalidParameterException, SimWafUnsimulatedInputException, } from "../error/sim-wafv2.error.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Stop compiling a rule at something real WAFv2 takes and this simulation does
|
|
4
4
|
* not.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* `SimWafRule.compile` catches it and holds the rule unevaluated, with this
|
|
7
|
+
* message as the reason the web ACL reports. The message names the rule and
|
|
8
|
+
* what in it was left out, because a web ACL is a list of rules that all look
|
|
9
|
+
* alike from the outside and the name is the only thing that says which one to
|
|
10
|
+
* go and look at.
|
|
9
11
|
*/
|
|
10
12
|
export function refuseSimWafRuleInput(ruleName, refused, reason) {
|
|
11
13
|
throw new SimWafUnsimulatedInputException(`Rule ${ruleName} uses ${refused}, which Yulin does not simulate: ` +
|
|
12
|
-
`${reason}.
|
|
13
|
-
`allow a request AWS blocks.`);
|
|
14
|
+
`${reason}. The rule is held and claims no request.`);
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* Refuse a rule real WAFv2 would refuse too.
|
|
@@ -19,8 +19,8 @@ export interface SimWafStatementScope {
|
|
|
19
19
|
* Turn one statement into the matcher a rule evaluates a request with.
|
|
20
20
|
*
|
|
21
21
|
* Compiling happens when the web ACL is written rather than when a request
|
|
22
|
-
* arrives, which is
|
|
23
|
-
*
|
|
24
|
-
* meets is a closure over what the rule already worked out.
|
|
22
|
+
* arrives, which is where a statement kind Yulin cannot evaluate is found and
|
|
23
|
+
* its rule held unevaluated. It also means a rule does no parsing per request:
|
|
24
|
+
* what a request meets is a closure over what the rule already worked out.
|
|
25
25
|
*/
|
|
26
26
|
export declare function compileSimWafStatement(statement: SimWafStatementInput | undefined, scope: SimWafStatementScope): SimWafMatcher;
|
|
@@ -11,9 +11,9 @@ import { refuseUnsimulatedSimWafStatement } from "./sim-waf-unsimulated-statemen
|
|
|
11
11
|
* Turn one statement into the matcher a rule evaluates a request with.
|
|
12
12
|
*
|
|
13
13
|
* Compiling happens when the web ACL is written rather than when a request
|
|
14
|
-
* arrives, which is
|
|
15
|
-
*
|
|
16
|
-
* meets is a closure over what the rule already worked out.
|
|
14
|
+
* arrives, which is where a statement kind Yulin cannot evaluate is found and
|
|
15
|
+
* its rule held unevaluated. It also means a rule does no parsing per request:
|
|
16
|
+
* what a request meets is a closure over what the rule already worked out.
|
|
17
17
|
*/
|
|
18
18
|
export function compileSimWafStatement(statement, scope) {
|
|
19
19
|
const { ruleName } = scope;
|
|
@@ -16,9 +16,9 @@ export interface SimWafFieldStatementInput {
|
|
|
16
16
|
/**
|
|
17
17
|
* Minimal structural WAFv2 Statement.
|
|
18
18
|
*
|
|
19
|
-
* The kinds Yulin
|
|
20
|
-
* rule that uses one is
|
|
21
|
-
* statement in it.
|
|
19
|
+
* The kinds Yulin does not evaluate are declared alongside the ones it does,
|
|
20
|
+
* so a rule that uses one is held and reported by name rather than read as a
|
|
21
|
+
* rule with no statement in it.
|
|
22
22
|
*
|
|
23
23
|
* https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/wafv2/Interface/Statement/
|
|
24
24
|
*/
|
|
@@ -6,7 +6,7 @@ const undocumentedDetection = "AWS does not document the detection it runs, so a
|
|
|
6
6
|
"agree with real WAF by coincidence or not at all";
|
|
7
7
|
/**
|
|
8
8
|
* The statement kinds real WAFv2 evaluates and this simulation does not, and
|
|
9
|
-
* why
|
|
9
|
+
* why a rule using one is held unevaluated.
|
|
10
10
|
*/
|
|
11
11
|
const refusedStatements = new Map([
|
|
12
12
|
["IPSetReferenceStatement", oneClientAddress],
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { SimWafUnsimulatedPart } from "../resource/sim-waf-unsimulated-part.js";
|
|
1
2
|
/**
|
|
2
3
|
* A resource type whose body inspection limit a web ACL can set.
|
|
3
4
|
*
|
|
4
5
|
* Real WAF keys `AssociationConfig.RequestBody` by resource type, and these
|
|
5
|
-
* three are the ones a
|
|
6
|
-
* `VERIFIED_ACCESS_INSTANCE` are keys AWS takes for resources
|
|
7
|
-
*
|
|
6
|
+
* three are the ones a request reaches a web ACL through here. `APP_RUNNER_SERVICE`
|
|
7
|
+
* and `VERIFIED_ACCESS_INSTANCE` are keys AWS takes for resources a web ACL
|
|
8
|
+
* can be associated with and no simulated request passes through.
|
|
8
9
|
*/
|
|
9
10
|
export type SimWafBodyInspectionResourceType = "CLOUDFRONT" | "API_GATEWAY" | "COGNITO_USER_POOL";
|
|
10
11
|
/**
|
|
@@ -12,8 +13,8 @@ export type SimWafBodyInspectionResourceType = "CLOUDFRONT" | "API_GATEWAY" | "C
|
|
|
12
13
|
* `AssociationConfig`.
|
|
13
14
|
*
|
|
14
15
|
* CloudFront, API Gateway and Cognito all default to 16 KB. A load balancer
|
|
15
|
-
* and an AppSync API are fixed at 8 KB, and
|
|
16
|
-
*
|
|
16
|
+
* and an AppSync API are fixed at 8 KB, and no simulated request reaches a web
|
|
17
|
+
* ACL through either one.
|
|
17
18
|
*/
|
|
18
19
|
export declare const simWafBodyInspectionLimitBytes = 16384;
|
|
19
20
|
/**
|
|
@@ -40,9 +41,15 @@ export declare class SimWafBodyInspectionLimits {
|
|
|
40
41
|
private constructor();
|
|
41
42
|
/**
|
|
42
43
|
* Read the limits an `AssociationConfig` sets, refusing anything WAF would
|
|
43
|
-
* refuse
|
|
44
|
+
* refuse.
|
|
44
45
|
*/
|
|
45
46
|
static read(input: SimWafAssociationConfigInput | undefined): SimWafBodyInspectionLimits;
|
|
47
|
+
/**
|
|
48
|
+
* The limits set for resource types no simulated request passes through.
|
|
49
|
+
*
|
|
50
|
+
* Each is checked as WAF checks it and held, and applies to nothing.
|
|
51
|
+
*/
|
|
52
|
+
get unsimulated(): readonly SimWafUnsimulatedPart[];
|
|
46
53
|
/**
|
|
47
54
|
* How many bytes of a body a request reaching one resource type is inspected
|
|
48
55
|
* for.
|
|
@@ -50,5 +57,5 @@ export declare class SimWafBodyInspectionLimits {
|
|
|
50
57
|
* A request evaluated against a web ACL that no resource holds names no
|
|
51
58
|
* resource type, and reads the default.
|
|
52
59
|
*/
|
|
53
|
-
bytesFor(resourceType:
|
|
60
|
+
bytesFor(resourceType: string | undefined): number;
|
|
54
61
|
}
|