@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
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ARN shapes AWS documents for each of them.
|
|
3
|
+
*/
|
|
4
|
+
const kinds = [
|
|
5
|
+
{
|
|
6
|
+
resourceType: "APPLICATION_LOAD_BALANCER",
|
|
7
|
+
described: "an Application Load Balancer",
|
|
8
|
+
pattern: /^arn:aws:elasticloadbalancing:[^:]+:[^:]+:loadbalancer\/app\/[^/]+\/[^/]+$/u,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
resourceType: "APPSYNC",
|
|
12
|
+
described: "an AppSync GraphQL API",
|
|
13
|
+
pattern: /^arn:aws:appsync:[^:]+:[^:]+:apis\/[^/]+$/u,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
resourceType: "APP_RUNNER_SERVICE",
|
|
17
|
+
described: "an App Runner service",
|
|
18
|
+
pattern: /^arn:aws:apprunner:[^:]+:[^:]+:service\/[^/]+\/[^/]+$/u,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
resourceType: "VERIFIED_ACCESS_INSTANCE",
|
|
22
|
+
described: "a Verified Access instance",
|
|
23
|
+
pattern: /^arn:aws:ec2:[^:]+:[^:]+:verified-access-instance\/[^/]+$/u,
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* The types listed for a resource AWS WAF protects and Yulin does not.
|
|
28
|
+
*/
|
|
29
|
+
export const simWafUnsimulatedResourceTypes = kinds.map((kind) => kind.resourceType);
|
|
30
|
+
/**
|
|
31
|
+
* A resource AWS WAF protects and no simulated request passes through.
|
|
32
|
+
*
|
|
33
|
+
* An association with one is held, and GetWebACLForResource and
|
|
34
|
+
* ListResourcesForWebACL report it. Nothing is evaluated in front of it,
|
|
35
|
+
* because nothing here serves a request through it. Whether the resource
|
|
36
|
+
* exists is not checked, since no simulated service holds it to ask.
|
|
37
|
+
*/
|
|
38
|
+
export class SimWafUnsimulatedResource {
|
|
39
|
+
resourceType;
|
|
40
|
+
arn;
|
|
41
|
+
regionName;
|
|
42
|
+
accountId;
|
|
43
|
+
/** Why the web ACL in front of this resource evaluates nothing. */
|
|
44
|
+
reason;
|
|
45
|
+
constructor(arn, kind) {
|
|
46
|
+
const [regionName, accountId] = arn.split(":").slice(3, 5);
|
|
47
|
+
this.resourceType = kind.resourceType;
|
|
48
|
+
this.arn = arn;
|
|
49
|
+
this.regionName = String(regionName);
|
|
50
|
+
this.accountId = String(accountId);
|
|
51
|
+
this.reason =
|
|
52
|
+
`AWS WAF protects ${kind.described}, and no simulated request passes ` +
|
|
53
|
+
`through one, so the association with ${arn} is held and nothing in ` +
|
|
54
|
+
`front of it is evaluated`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The unsimulated resource an ARN names, or nothing when it names none.
|
|
58
|
+
*
|
|
59
|
+
* Every pattern places the Region and the Account where any ARN does, so a
|
|
60
|
+
* match is read for them by position.
|
|
61
|
+
*/
|
|
62
|
+
static read(arn) {
|
|
63
|
+
const kind = kinds.find((candidate) => candidate.pattern.test(arn));
|
|
64
|
+
return kind && new SimWafUnsimulatedResource(arn, kind);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SimWafUnsimulatedResource } from "../../association/sim-waf-unsimulated-resource.js";
|
|
1
2
|
import { SimWafUnavailableEntityException } from "../../error/sim-wafv2.error.js";
|
|
2
3
|
import { simCfnWafResourceCommand } from "../sim-cfn-waf-resource-error.js";
|
|
3
4
|
import { wafWebAclAssociationResourceType } from "../sim-cfn-waf-resource-types.js";
|
|
@@ -44,6 +45,10 @@ export class SimCfnWafAssociationCreator {
|
|
|
44
45
|
WebACLArn: association.webAclArn,
|
|
45
46
|
},
|
|
46
47
|
}, options);
|
|
48
|
+
const unsimulated = SimWafUnsimulatedResource.read(association.resourceArn);
|
|
49
|
+
if (unsimulated !== undefined) {
|
|
50
|
+
resource.ignoreProperty("ResourceArn", unsimulated.reason);
|
|
51
|
+
}
|
|
47
52
|
return association;
|
|
48
53
|
});
|
|
49
54
|
}
|
|
@@ -20,6 +20,7 @@ export class SimCfnWafIpSetConfig extends SimCfnWafResourceConfig {
|
|
|
20
20
|
Name: this.name(),
|
|
21
21
|
Scope: this.scope(),
|
|
22
22
|
Description: this.description(),
|
|
23
|
+
Tags: this.tags(),
|
|
23
24
|
IPAddressVersion: this.text("IPAddressVersion"),
|
|
24
25
|
Addresses: this.requiredStrings("Addresses"),
|
|
25
26
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertDefined } from "../../../../util/type-guard/defined.js";
|
|
2
2
|
import { simCfnWafResourceCommand } from "../sim-cfn-waf-resource-error.js";
|
|
3
|
+
import { simCfnWafRecordUnsimulated } from "../sim-cfn-waf-unsimulated.js";
|
|
3
4
|
import { wafIpSetResourceType } from "../sim-cfn-waf-resource-types.js";
|
|
4
5
|
import { SimCfnWafIpSetConfig } from "./sim-cfn-waf-ip-set-config.js";
|
|
5
6
|
/**
|
|
@@ -29,6 +30,7 @@ export class SimCfnWafIpSetCreator {
|
|
|
29
30
|
assertDefined(arn, `sim WAFv2 IP set ARN for CloudFormation Resource ${resource.logicalId}`);
|
|
30
31
|
const ipSet = this.#wafV2.findIpSetByArn(arn);
|
|
31
32
|
assertDefined(ipSet, `sim WAFv2 IP set ${arn} after CloudFormation creation`);
|
|
33
|
+
simCfnWafRecordUnsimulated(resource, ipSet);
|
|
32
34
|
return ipSet;
|
|
33
35
|
});
|
|
34
36
|
}
|
|
@@ -21,6 +21,7 @@ export class SimCfnWafRegexPatternSetConfig extends SimCfnWafResourceConfig {
|
|
|
21
21
|
Name: this.name(),
|
|
22
22
|
Scope: this.scope(),
|
|
23
23
|
Description: this.description(),
|
|
24
|
+
Tags: this.tags(),
|
|
24
25
|
RegularExpressionList: this.requiredStrings("RegularExpressionList").map((pattern) => ({ RegexString: pattern })),
|
|
25
26
|
};
|
|
26
27
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assertDefined } from "../../../../util/type-guard/defined.js";
|
|
2
2
|
import { simCfnWafResourceCommand } from "../sim-cfn-waf-resource-error.js";
|
|
3
|
+
import { simCfnWafRecordUnsimulated } from "../sim-cfn-waf-unsimulated.js";
|
|
3
4
|
import { wafRegexPatternSetResourceType } from "../sim-cfn-waf-resource-types.js";
|
|
4
5
|
import { SimCfnWafRegexPatternSetConfig } from "./sim-cfn-waf-regex-set-config.js";
|
|
5
6
|
/**
|
|
@@ -29,6 +30,7 @@ export class SimCfnWafRegexPatternSetCreator {
|
|
|
29
30
|
assertDefined(arn, `sim WAFv2 regex pattern set ARN for CloudFormation Resource ${resource.logicalId}`);
|
|
30
31
|
const patternSet = this.#wafV2.findRegexPatternSetByArn(arn);
|
|
31
32
|
assertDefined(patternSet, `sim WAFv2 regex pattern set ${arn} after CloudFormation creation`);
|
|
33
|
+
simCfnWafRecordUnsimulated(resource, patternSet);
|
|
32
34
|
return patternSet;
|
|
33
35
|
});
|
|
34
36
|
}
|
|
@@ -45,6 +45,10 @@ export declare abstract class SimCfnWafResourceConfig {
|
|
|
45
45
|
/**
|
|
46
46
|
* One property of the Resource, whatever shape it is in.
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* The tags the template gave the Resource, as written.
|
|
50
|
+
*/
|
|
51
|
+
tags(): readonly unknown[] | undefined;
|
|
48
52
|
protected value(key: string): SimCfnTemplateValue | undefined;
|
|
49
53
|
/**
|
|
50
54
|
* One string property, or nothing when the template left it out.
|
|
@@ -57,6 +57,16 @@ export class SimCfnWafResourceConfig {
|
|
|
57
57
|
/**
|
|
58
58
|
* One property of the Resource, whatever shape it is in.
|
|
59
59
|
*/
|
|
60
|
+
/**
|
|
61
|
+
* The tags the template gave the Resource, as written.
|
|
62
|
+
*/
|
|
63
|
+
tags() {
|
|
64
|
+
const tags = this.value("Tags");
|
|
65
|
+
if (tags !== undefined && !Array.isArray(tags)) {
|
|
66
|
+
this.refuse("Tags must be a list");
|
|
67
|
+
}
|
|
68
|
+
return tags;
|
|
69
|
+
}
|
|
60
70
|
value(key) {
|
|
61
71
|
// oxlint-disable-next-line security/detect-object-injection
|
|
62
72
|
return this.properties[key] ?? undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SimCfnResource } from "../../cloudformation/resource/sim-cfn-resource.js";
|
|
2
|
+
import type { SimWafResource } from "../resource/sim-waf-resource.js";
|
|
3
|
+
/**
|
|
4
|
+
* Record on a Resource each part of the WAFv2 resource it created that the
|
|
5
|
+
* simulation holds and does not act on.
|
|
6
|
+
*
|
|
7
|
+
* The path is the one `unsimulatedParts` reports, so `stack.ignoredProperties`
|
|
8
|
+
* and an SDK caller read the same names.
|
|
9
|
+
*/
|
|
10
|
+
export declare function simCfnWafRecordUnsimulated(resource: SimCfnResource, created: SimWafResource): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record on a Resource each part of the WAFv2 resource it created that the
|
|
3
|
+
* simulation holds and does not act on.
|
|
4
|
+
*
|
|
5
|
+
* The path is the one `unsimulatedParts` reports, so `stack.ignoredProperties`
|
|
6
|
+
* and an SDK caller read the same names.
|
|
7
|
+
*/
|
|
8
|
+
export function simCfnWafRecordUnsimulated(resource, created) {
|
|
9
|
+
for (const { part, reason } of created.unsimulated) {
|
|
10
|
+
resource.ignoreProperty(part, reason);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -8,26 +8,14 @@ import { SimCfnWafResourceConfig } from "../sim-cfn-waf-resource-config.js";
|
|
|
8
8
|
* template wrote them. They are not read here at all: every rule is compiled
|
|
9
9
|
* by CreateWebACL, which is where a statement kind Yulin cannot evaluate is
|
|
10
10
|
* found, and reading them twice would mean two answers to the same question.
|
|
11
|
+
* The members Yulin holds without acting on are handed over the same way.
|
|
11
12
|
*/
|
|
12
13
|
export declare class SimCfnWafWebAclConfig extends SimCfnWafResourceConfig {
|
|
13
14
|
protected get resourceType(): string;
|
|
14
15
|
/**
|
|
15
16
|
* The input the web ACL this Resource describes is created from.
|
|
16
|
-
*
|
|
17
|
-
* The properties this simulation has no behaviour for are left out of it and
|
|
18
|
-
* recorded, so the web ACL deploys with the rest of what the template wrote.
|
|
19
|
-
* An SDK caller is refused for the same properties, because a request that
|
|
20
|
-
* was answered and then quietly dropped is a worse answer than a refusal.
|
|
21
17
|
*/
|
|
22
18
|
createInput(): SimCreateWebAclCommandInput;
|
|
23
|
-
/**
|
|
24
|
-
* Record the web ACL members this simulation has no behaviour for.
|
|
25
|
-
*
|
|
26
|
-
* Each of them changes what a web ACL does on real WAF, so a web ACL
|
|
27
|
-
* deployed without one behaves differently to the one the template
|
|
28
|
-
* describes. `stack.ignoredProperties` is where a test reads that.
|
|
29
|
-
*/
|
|
30
|
-
private recordUnsimulatedMembers;
|
|
31
19
|
/**
|
|
32
20
|
* The rules the template declared.
|
|
33
21
|
*
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { simWafUnsimulatedWebAclMembers } from "../../command/web-acl/sim-wafv2-unsimulated-web-acl-input.js";
|
|
2
1
|
import { SimCfnWafResourceConfig } from "../sim-cfn-waf-resource-config.js";
|
|
3
2
|
import { wafWebAclResourceType } from "../sim-cfn-waf-resource-types.js";
|
|
4
3
|
/**
|
|
@@ -9,6 +8,7 @@ import { wafWebAclResourceType } from "../sim-cfn-waf-resource-types.js";
|
|
|
9
8
|
* template wrote them. They are not read here at all: every rule is compiled
|
|
10
9
|
* by CreateWebACL, which is where a statement kind Yulin cannot evaluate is
|
|
11
10
|
* found, and reading them twice would mean two answers to the same question.
|
|
11
|
+
* The members Yulin holds without acting on are handed over the same way.
|
|
12
12
|
*/
|
|
13
13
|
export class SimCfnWafWebAclConfig extends SimCfnWafResourceConfig {
|
|
14
14
|
get resourceType() {
|
|
@@ -16,39 +16,26 @@ export class SimCfnWafWebAclConfig extends SimCfnWafResourceConfig {
|
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* The input the web ACL this Resource describes is created from.
|
|
19
|
-
*
|
|
20
|
-
* The properties this simulation has no behaviour for are left out of it and
|
|
21
|
-
* recorded, so the web ACL deploys with the rest of what the template wrote.
|
|
22
|
-
* An SDK caller is refused for the same properties, because a request that
|
|
23
|
-
* was answered and then quietly dropped is a worse answer than a refusal.
|
|
24
19
|
*/
|
|
25
20
|
createInput() {
|
|
26
|
-
this.recordUnsimulatedMembers();
|
|
27
21
|
return {
|
|
28
22
|
Name: this.name(),
|
|
29
23
|
Scope: this.scope(),
|
|
30
24
|
Description: this.description(),
|
|
25
|
+
Tags: this.tags(),
|
|
31
26
|
DefaultAction: this.value("DefaultAction"),
|
|
32
27
|
Rules: this.rules(),
|
|
33
28
|
VisibilityConfig: this.value("VisibilityConfig"),
|
|
34
29
|
CustomResponseBodies: this.value("CustomResponseBodies"),
|
|
35
30
|
AssociationConfig: this.value("AssociationConfig"),
|
|
31
|
+
CaptchaConfig: this.value("CaptchaConfig"),
|
|
32
|
+
ChallengeConfig: this.value("ChallengeConfig"),
|
|
33
|
+
TokenDomains: this.value("TokenDomains"),
|
|
34
|
+
DataProtectionConfig: this.value("DataProtectionConfig"),
|
|
35
|
+
OnSourceDDoSProtectionConfig: this.value("OnSourceDDoSProtectionConfig"),
|
|
36
|
+
ApplicationConfig: this.value("ApplicationConfig"),
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Record the web ACL members this simulation has no behaviour for.
|
|
40
|
-
*
|
|
41
|
-
* Each of them changes what a web ACL does on real WAF, so a web ACL
|
|
42
|
-
* deployed without one behaves differently to the one the template
|
|
43
|
-
* describes. `stack.ignoredProperties` is where a test reads that.
|
|
44
|
-
*/
|
|
45
|
-
recordUnsimulatedMembers() {
|
|
46
|
-
for (const [member, reason] of simWafUnsimulatedWebAclMembers) {
|
|
47
|
-
if (this.value(member) !== undefined) {
|
|
48
|
-
this.resource.ignoreProperty(member, `${member} is not simulated: ${reason}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
39
|
/**
|
|
53
40
|
* The rules the template declared.
|
|
54
41
|
*
|
|
@@ -14,15 +14,10 @@ interface SimCfnWafWebAclCreatorProperties {
|
|
|
14
14
|
* caller would have got: the same compilation of every rule, and the same
|
|
15
15
|
* refusals.
|
|
16
16
|
*
|
|
17
|
-
* A rule this simulation cannot
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* user pool, a table and two functions in the same template down with it.
|
|
22
|
-
*
|
|
23
|
-
* The web ACL is then real, and thinner than the one the template describes.
|
|
24
|
-
* That is the cost of deploying it at all, and the record of the dropped rule
|
|
25
|
-
* is what a test reads to know the size of it.
|
|
17
|
+
* A rule or member this simulation cannot act on is held by the web ACL as the
|
|
18
|
+
* template wrote it, and recorded on `stack.ignoredProperties` under the name
|
|
19
|
+
* the web ACL reports it by. That record is what a test reads to know how far
|
|
20
|
+
* the deployed web ACL is from the one AWS would run.
|
|
26
21
|
*/
|
|
27
22
|
export declare class SimCfnWafWebAclCreator {
|
|
28
23
|
#private;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assertDefined } from "../../../../util/type-guard/defined.js";
|
|
2
2
|
import { simCfnWafResourceCommand } from "../sim-cfn-waf-resource-error.js";
|
|
3
|
+
import { simCfnWafRecordUnsimulated } from "../sim-cfn-waf-unsimulated.js";
|
|
3
4
|
import { wafWebAclResourceType } from "../sim-cfn-waf-resource-types.js";
|
|
4
|
-
import { simCfnWafEvaluatableRules } from "./sim-cfn-waf-evaluatable-rules.js";
|
|
5
5
|
import { SimCfnWafWebAclConfig } from "./sim-cfn-waf-web-acl-config.js";
|
|
6
6
|
/**
|
|
7
7
|
* Creates simulated web ACLs from AWS::WAFv2::WebACL Resources.
|
|
@@ -11,15 +11,10 @@ import { SimCfnWafWebAclConfig } from "./sim-cfn-waf-web-acl-config.js";
|
|
|
11
11
|
* caller would have got: the same compilation of every rule, and the same
|
|
12
12
|
* refusals.
|
|
13
13
|
*
|
|
14
|
-
* A rule this simulation cannot
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* user pool, a table and two functions in the same template down with it.
|
|
19
|
-
*
|
|
20
|
-
* The web ACL is then real, and thinner than the one the template describes.
|
|
21
|
-
* That is the cost of deploying it at all, and the record of the dropped rule
|
|
22
|
-
* is what a test reads to know the size of it.
|
|
14
|
+
* A rule or member this simulation cannot act on is held by the web ACL as the
|
|
15
|
+
* template wrote it, and recorded on `stack.ignoredProperties` under the name
|
|
16
|
+
* the web ACL reports it by. That record is what a test reads to know how far
|
|
17
|
+
* the deployed web ACL is from the one AWS would run.
|
|
23
18
|
*/
|
|
24
19
|
export class SimCfnWafWebAclCreator {
|
|
25
20
|
#wafV2;
|
|
@@ -34,16 +29,13 @@ export class SimCfnWafWebAclCreator {
|
|
|
34
29
|
resource,
|
|
35
30
|
properties,
|
|
36
31
|
}).createInput();
|
|
37
|
-
const deployable = {
|
|
38
|
-
...input,
|
|
39
|
-
Rules: simCfnWafEvaluatableRules(this.#wafV2, resource, input),
|
|
40
|
-
};
|
|
41
32
|
return await simCfnWafResourceCommand(wafWebAclResourceType, resource.logicalId, async () => {
|
|
42
|
-
const created = await this.#wafV2.createWebAcl({ input
|
|
33
|
+
const created = await this.#wafV2.createWebAcl({ input }, options);
|
|
43
34
|
const arn = created.Summary?.ARN;
|
|
44
35
|
assertDefined(arn, `sim WAFv2 web ACL ARN for CloudFormation Resource ${resource.logicalId}`);
|
|
45
36
|
const webAcl = this.#wafV2.findWebAclByArn(arn);
|
|
46
37
|
assertDefined(webAcl, `sim WAFv2 web ACL ${arn} after CloudFormation creation`);
|
|
38
|
+
simCfnWafRecordUnsimulated(resource, webAcl);
|
|
47
39
|
return webAcl;
|
|
48
40
|
});
|
|
49
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { requiredSimWafArn } from "../sim-wafv2-input.js";
|
|
2
2
|
import { simWafWebAclOutput } from "../web-acl/sim-waf-web-acl-output.js";
|
|
3
|
-
import { simWafListedResourceType } from "./sim-wafv2-association-input.js";
|
|
3
|
+
import { refuseSimWafAccountTakeoverForUserPool, simWafListedResourceType, } from "./sim-wafv2-association-input.js";
|
|
4
4
|
/**
|
|
5
5
|
* The commands that put a web ACL in front of a resource and take it away
|
|
6
6
|
* again.
|
|
@@ -27,6 +27,7 @@ export class SimWafAssociationCommands {
|
|
|
27
27
|
this.#access.authorizeWebAcl("wafv2:AssociateWebACL", webAclArn, options?.caller);
|
|
28
28
|
const webAcl = this.#access.webAcl(webAclArn);
|
|
29
29
|
this.#access.requireResource(resource);
|
|
30
|
+
refuseSimWafAccountTakeoverForUserPool(resource, webAcl);
|
|
30
31
|
this.#associations.associate(resource, webAcl);
|
|
31
32
|
return { $metadata: {} };
|
|
32
33
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SimAwsAccountRegionScope } from "../../../aws/sim-aws-account-region-scope.js";
|
|
2
2
|
import { type SimWafProtectedResource, type SimWafProtectedResourceType } from "../../association/sim-waf-protected-resource.js";
|
|
3
|
+
import type { SimWafWebAcl } from "../../web-acl/sim-waf-web-acl.js";
|
|
3
4
|
/**
|
|
4
5
|
* Read the resource an association named, and hold it to one Account and
|
|
5
6
|
* Region.
|
|
@@ -11,7 +12,14 @@ import { type SimWafProtectedResource, type SimWafProtectedResourceType } from "
|
|
|
11
12
|
*/
|
|
12
13
|
export declare function simWafAssociationResource(resourceArn: string | undefined, accountRegionScope: SimAwsAccountRegionScope): SimWafProtectedResource;
|
|
13
14
|
/**
|
|
14
|
-
* Read the resource type a listing named, refusing one
|
|
15
|
-
* not hold.
|
|
15
|
+
* Read the resource type a listing named, refusing one WAFv2 does not list.
|
|
16
16
|
*/
|
|
17
17
|
export declare function simWafListedResourceType(resourceType: string | undefined): SimWafProtectedResourceType;
|
|
18
|
+
/**
|
|
19
|
+
* Refuse a web ACL carrying the account takeover group in front of a user
|
|
20
|
+
* pool, as AWS does.
|
|
21
|
+
*
|
|
22
|
+
* AWS refuses the whole association over the one rule group. Yulin holds the
|
|
23
|
+
* group without evaluating it, and this is where the refusal lands.
|
|
24
|
+
*/
|
|
25
|
+
export declare function refuseSimWafAccountTakeoverForUserPool(resource: SimWafProtectedResource, webAcl: SimWafWebAcl): void;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { simWafProtectedResource, simWafProtectedResourceTypes, } from "../../association/sim-waf-protected-resource.js";
|
|
2
|
-
import { SimWafInvalidParameterException
|
|
2
|
+
import { SimWafInvalidParameterException } from "../../error/sim-wafv2.error.js";
|
|
3
3
|
import { requiredSimWafArn } from "../sim-wafv2-input.js";
|
|
4
4
|
/**
|
|
5
|
-
* What ListResourcesForWebACL lists when the request names no resource type
|
|
6
|
-
*
|
|
7
|
-
* Real WAFv2 documents that default, and it is not one of the types simulated
|
|
8
|
-
* here. A listing that names nothing is refused, because the empty list a load
|
|
9
|
-
* balancer listing produces reads as a web ACL protecting nothing.
|
|
5
|
+
* What ListResourcesForWebACL lists when the request names no resource type,
|
|
6
|
+
* as real WAFv2 documents it.
|
|
10
7
|
*/
|
|
11
8
|
const defaultResourceType = "APPLICATION_LOAD_BALANCER";
|
|
12
9
|
/**
|
|
@@ -32,21 +29,36 @@ export function simWafAssociationResource(resourceArn, accountRegionScope) {
|
|
|
32
29
|
return resource;
|
|
33
30
|
}
|
|
34
31
|
/**
|
|
35
|
-
* Read the resource type a listing named, refusing one
|
|
36
|
-
* not hold.
|
|
32
|
+
* Read the resource type a listing named, refusing one WAFv2 does not list.
|
|
37
33
|
*/
|
|
38
34
|
export function simWafListedResourceType(resourceType) {
|
|
39
35
|
const listed = resourceType ?? defaultResourceType;
|
|
40
36
|
const simulated = simWafProtectedResourceTypes.find((candidate) => candidate === listed);
|
|
41
37
|
if (simulated === undefined) {
|
|
42
|
-
throw new
|
|
43
|
-
`${simWafProtectedResourceTypes.join("
|
|
44
|
-
`
|
|
45
|
-
`a request names no ResourceType, so name one of the simulated types ` +
|
|
46
|
-
`to list the resources a web ACL protects.`);
|
|
38
|
+
throw new SimWafInvalidParameterException(`Error reason: ListResourcesForWebACL lists one of ` +
|
|
39
|
+
`${simWafProtectedResourceTypes.join(", ")}, field: RESOURCE_TYPE, ` +
|
|
40
|
+
`parameter: ${listed}`);
|
|
47
41
|
}
|
|
48
42
|
return simulated;
|
|
49
43
|
}
|
|
44
|
+
const accountTakeoverGroup = "AWSManagedRulesATPRuleSet";
|
|
45
|
+
/**
|
|
46
|
+
* Refuse a web ACL carrying the account takeover group in front of a user
|
|
47
|
+
* pool, as AWS does.
|
|
48
|
+
*
|
|
49
|
+
* AWS refuses the whole association over the one rule group. Yulin holds the
|
|
50
|
+
* group without evaluating it, and this is where the refusal lands.
|
|
51
|
+
*/
|
|
52
|
+
export function refuseSimWafAccountTakeoverForUserPool(resource, webAcl) {
|
|
53
|
+
if (resource.resourceType !== "COGNITO_USER_POOL") {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const carriesGroup = (webAcl.configuration.rules ?? []).some((rule) => rule.Statement?.ManagedRuleGroupStatement?.Name === accountTakeoverGroup);
|
|
57
|
+
if (carriesGroup) {
|
|
58
|
+
throw refusedResourceArn(`A web ACL carrying ${accountTakeoverGroup} cannot protect a Cognito ` +
|
|
59
|
+
`user pool`, resource.arn);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
50
62
|
/**
|
|
51
63
|
* The refusal a bad resource ARN reports, in the form WAFv2 writes.
|
|
52
64
|
*/
|
|
@@ -12,9 +12,9 @@ interface SimWafIpSetCommandsProperties {
|
|
|
12
12
|
/**
|
|
13
13
|
* The commands that make, read, list and remove IP sets.
|
|
14
14
|
*
|
|
15
|
-
* The addresses are held and reported and nothing evaluates them
|
|
16
|
-
* `IPSetReferenceStatement` is
|
|
17
|
-
* from 127.0.0.1.
|
|
15
|
+
* The addresses are held and reported and nothing evaluates them. A rule
|
|
16
|
+
* naming one with `IPSetReferenceStatement` is held unevaluated, because every
|
|
17
|
+
* request in this simulation comes from 127.0.0.1.
|
|
18
18
|
*/
|
|
19
19
|
export declare class SimWafIpSetCommands {
|
|
20
20
|
#private;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { SimWafIpSet, requiredSimWafIpAddressVersion, } from "../../ip-set/sim-waf-ip-set.js";
|
|
2
2
|
import { requiredSimWafScope } from "../../scope/sim-waf-scope.js";
|
|
3
3
|
import { SimWafPage } from "../sim-wafv2-page.js";
|
|
4
|
-
import { checkedSimWafDescription,
|
|
4
|
+
import { checkedSimWafDescription, requiredSimWafName, } from "../sim-wafv2-input.js";
|
|
5
5
|
import { requireSimWafResource } from "../sim-wafv2-resource-lookup.js";
|
|
6
6
|
/**
|
|
7
7
|
* The commands that make, read, list and remove IP sets.
|
|
8
8
|
*
|
|
9
|
-
* The addresses are held and reported and nothing evaluates them
|
|
10
|
-
* `IPSetReferenceStatement` is
|
|
11
|
-
* from 127.0.0.1.
|
|
9
|
+
* The addresses are held and reported and nothing evaluates them. A rule
|
|
10
|
+
* naming one with `IPSetReferenceStatement` is held unevaluated, because every
|
|
11
|
+
* request in this simulation comes from 127.0.0.1.
|
|
12
12
|
*/
|
|
13
13
|
export class SimWafIpSetCommands {
|
|
14
14
|
#ipSets;
|
|
@@ -24,12 +24,12 @@ export class SimWafIpSetCommands {
|
|
|
24
24
|
*/
|
|
25
25
|
createIpSet(command, options) {
|
|
26
26
|
const { input } = command;
|
|
27
|
-
refuseSimWafTags(input.Tags, "CreateIPSet");
|
|
28
27
|
const ipSet = new SimWafIpSet({
|
|
29
28
|
name: requiredSimWafName(input.Name),
|
|
30
29
|
scope: requiredSimWafScope(input.Scope, this.#accountRegionScope.regionName),
|
|
31
30
|
accountRegionScope: this.#accountRegionScope,
|
|
32
31
|
description: checkedSimWafDescription(input.Description),
|
|
32
|
+
tags: input.Tags,
|
|
33
33
|
ipAddressVersion: requiredSimWafIpAddressVersion(input.IPAddressVersion),
|
|
34
34
|
addresses: input.Addresses ?? [],
|
|
35
35
|
});
|
package/dist/service/wafv2/command/managed-rule-group/sim-wafv2-managed-rule-group-commands.js
CHANGED
|
@@ -30,11 +30,11 @@ export class SimWafManagedRuleGroupCommands {
|
|
|
30
30
|
LabelNamespace: `${group.labelNamespace}:`,
|
|
31
31
|
Rules: group.rules.map((rule) => ({
|
|
32
32
|
Name: rule.name,
|
|
33
|
-
Action: { Block: {} },
|
|
34
|
-
})),
|
|
35
|
-
AvailableLabels: group.rules.map((rule) => ({
|
|
36
|
-
Name: `${group.labelNamespace}:${rule.label}`,
|
|
33
|
+
Action: rule.counts === true ? { Count: {} } : { Block: {} },
|
|
37
34
|
})),
|
|
35
|
+
AvailableLabels: group.rules
|
|
36
|
+
.flatMap((rule) => [rule.label, ...(rule.labels ?? [])])
|
|
37
|
+
.map((label) => ({ Name: `${group.labelNamespace}:${label}` })),
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
}
|
package/dist/service/wafv2/command/regex-pattern-set/sim-wafv2-regex-pattern-set-commands.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SimWafRegexPatternSet } from "../../regex-pattern-set/sim-waf-regex-pattern-set.js";
|
|
2
2
|
import { requiredSimWafScope } from "../../scope/sim-waf-scope.js";
|
|
3
3
|
import { SimWafPage } from "../sim-wafv2-page.js";
|
|
4
|
-
import { checkedSimWafDescription,
|
|
4
|
+
import { checkedSimWafDescription, requiredSimWafName, } from "../sim-wafv2-input.js";
|
|
5
5
|
import { requireSimWafResource } from "../sim-wafv2-resource-lookup.js";
|
|
6
6
|
/**
|
|
7
7
|
* The commands that make, read, list and remove regex pattern sets.
|
|
@@ -24,12 +24,12 @@ export class SimWafRegexPatternSetCommands {
|
|
|
24
24
|
*/
|
|
25
25
|
createRegexPatternSet(command, options) {
|
|
26
26
|
const { input } = command;
|
|
27
|
-
refuseSimWafTags(input.Tags, "CreateRegexPatternSet");
|
|
28
27
|
const patternSet = new SimWafRegexPatternSet({
|
|
29
28
|
name: requiredSimWafName(input.Name),
|
|
30
29
|
scope: requiredSimWafScope(input.Scope, this.#accountRegionScope.regionName),
|
|
31
30
|
accountRegionScope: this.#accountRegionScope,
|
|
32
31
|
description: checkedSimWafDescription(input.Description),
|
|
32
|
+
tags: input.Tags,
|
|
33
33
|
regularExpressions: input.RegularExpressionList ?? [],
|
|
34
34
|
});
|
|
35
35
|
this.#authorizer.authorizeResource("wafv2:CreateRegexPatternSet", patternSet.arn, options?.caller);
|
|
@@ -10,13 +10,6 @@ export declare function requiredSimWafName(name: string | undefined): string;
|
|
|
10
10
|
* read, and so does this.
|
|
11
11
|
*/
|
|
12
12
|
export declare function requiredSimWafId(id: string | undefined): string;
|
|
13
|
-
/**
|
|
14
|
-
* Refuse tags on a WAFv2 resource.
|
|
15
|
-
*
|
|
16
|
-
* Nothing here reads a tag, and a resource that reported tags it was never
|
|
17
|
-
* asked about would be worse than one that says it does not carry them.
|
|
18
|
-
*/
|
|
19
|
-
export declare function refuseSimWafTags(tags: readonly unknown[] | undefined, operation: string): void;
|
|
20
13
|
/**
|
|
21
14
|
* Read an ARN a request named, refusing a request with none.
|
|
22
15
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SimWafInvalidParameterException,
|
|
1
|
+
import { SimWafInvalidParameterException, SimWafValidationException, } from "../error/sim-wafv2.error.js";
|
|
2
2
|
/**
|
|
3
3
|
* Read the name a request named, refusing a request with none.
|
|
4
4
|
*/
|
|
@@ -22,18 +22,6 @@ export function requiredSimWafId(id) {
|
|
|
22
22
|
}
|
|
23
23
|
return id;
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Refuse tags on a WAFv2 resource.
|
|
27
|
-
*
|
|
28
|
-
* Nothing here reads a tag, and a resource that reported tags it was never
|
|
29
|
-
* asked about would be worse than one that says it does not carry them.
|
|
30
|
-
*/
|
|
31
|
-
export function refuseSimWafTags(tags, operation) {
|
|
32
|
-
if (tags !== undefined && tags.length > 0) {
|
|
33
|
-
throw new SimWafUnsimulatedInputException(`WAFv2 resource tags are not simulated, so ${operation} refuses them ` +
|
|
34
|
-
`rather than dropping them`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
25
|
/**
|
|
38
26
|
* Read an ARN a request named, refusing a request with none.
|
|
39
27
|
*
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
+
import type { SimWafUnsimulatedPart } from "../../resource/sim-waf-unsimulated-part.js";
|
|
1
2
|
import type { SimWafWebAclWriteInput } from "./web-acl.command.js";
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
4
|
+
* The web ACL members a write carries that this simulation holds without
|
|
5
|
+
* acting on, keyed by member name.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Each of them changes what a web ACL does on real WAF. The web ACL keeps
|
|
8
|
+
* them, `GetWebACL` returns them as written, and `unsimulatedSimWafWebAclMembers`
|
|
9
|
+
* says which ones a request evaluated here goes without.
|
|
9
10
|
*/
|
|
10
|
-
export declare
|
|
11
|
+
export declare function heldSimWafWebAclMembers(input: SimWafWebAclWriteInput): Readonly<Record<string, unknown>>;
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* Each of them changes what a web ACL does on real WAF, so accepting one and
|
|
15
|
-
* dropping it would leave the web ACL looking configured to the request that
|
|
16
|
-
* wrote it and unconfigured to every request it then evaluated.
|
|
13
|
+
* What a web ACL's held members leave out, one part per member.
|
|
17
14
|
*/
|
|
18
|
-
export declare function
|
|
15
|
+
export declare function unsimulatedSimWafWebAclMembers(members: Readonly<Record<string, unknown>>): readonly SimWafUnsimulatedPart[];
|