Repository: cdklabs/cdk-validator-cfnguard (language: python)

Issue:
cdk synth error
Steps:
1. npm install @cdklabs/cdk-validator-cfnguard
    Ref: https://docs.aws.amazon.com/cdk/v2/guide/policy-validation-synthesis.html
2. cdk synth
3. cdk --version
2.70.0 (build c13a0f1)


```

const app = new App({
  policyValidationBeta1: [
    new CfnGuardValidator()
  ],
});


Validation Report
-----------------

╔════════════════════════════════════╗
║           Plugin Report            ║
║   Plugin: cdk-validator-cfnguard   ║
║   Version: N/A                     ║
║   Status: failure                  ║
╚════════════════════════════════════╝


Metadata: 
        error: Validation plugin 'cdk-validator-cfnguard' failed: 
        CfnGuardValidator plugin failed processing cfn-guard results.
        Please create an issue https://github.com/cdklabs/cdk-validator-cfnguard/issues/new
        Rule: ct-codebuild-pr-4.guard
        Error: TypeError: Cannot read properties of undefined (reading 'path')

Policy Validation Report Summary

╔════════════════════════╤═════════╗
║ Plugin                 │ Status  ║
╟────────────────────────┼─────────╢
║ cdk-validator-cfnguard │ failure ║
╚════════════════════════╧═════════╝

Validation failed. See the validation report above for details

Subprocess exited with error 1

```


Discussion / hints:
I also get a similar error. Here's the reproduction steps:

```sh
git clone -b cfn-guard git@github.com:aws-samples/serverless-full-stack-webapp-starter-kit.git repro
cd repro/cdk
npm ci
npx cdk synth
# get an error
```

In my case the error is raised here. `nestedValue.from` is sometimes `undefined`.
https://github.com/cdklabs/cdk-validator-cfnguard/blob/efcf60df1de60068aa3aa9b1666c30308e30ae67/src/plugin.ts#L338


@andsus @tmokmss thanks for reporting this! I should have a PR up to fix today.

@andsus can you provide the configuration for the codebuild project that is causing the error so that I can confirm that my fix fixes your issue as well?

Fix patch:
diff --git a/src/plugin.ts b/src/plugin.ts
index 0c1ac26..984f437 100644
--- a/src/plugin.ts
+++ b/src/plugin.ts
@@ -330,17 +330,32 @@ function extractNestedObject(object: any): any {
       // A check can either be resolved or unresolved
       case 'resolved':
       case 'inresolved':
-        newObject = {
-          resolved: true,
-          traversed: {
-            from: nestedValue.from,
-            to: {
-              path: nestedValue.from.path,
-              value: nestedValue.to.value,
+        if ('from' in nestedValue) {
+          newObject = {
+            resolved: true,
+            traversed: {
+              from: nestedValue.from,
+              to: {
+                path: nestedValue.from.path,
+                value: nestedValue.to.value,
+              },
             },
-          },
-          messages: nestedValue.messages,
-        };
+            messages: nestedValue.messages,
+          };
+        } else if ('value' in nestedValue) {
+          newObject = {
+            resolved: true,
+            traversed: {
+              from: nestedValue.value,
+              to: {
+                path: nestedValue.value.path,
+                value: nestedValue.value.value,
+              },
+            },
+            messages: nestedValue.messages,
+          };
+
+        }
         break;
     }
     // this check will be evaluated _after_ the 'traversed_to' check and _before_ the 'resolved'


Test patch:
diff --git a/test/plugin.test.ts b/test/plugin.test.ts
index ebb153b..3cc5f53 100644
--- a/test/plugin.test.ts
+++ b/test/plugin.test.ts
@@ -418,6 +418,40 @@ describe('CfnGuardPlugin', () => {
     });
   });
 
+  test('guard-disjunctions-checks', () => {
+    // GIVEN
+    execMock.mockReturnValue(getData('guard-disjunction-resolved-check.json'));
+    const validator = new plugin.CfnGuardValidator();
+
+    // WHEN
+    const result = validator.validate({
+      templatePaths: ['./tmp'],
+    });
+
+    // THEN
+    expect(result).toEqual({
+      success: false,
+      violations: [{
+        description: '[CT.CLOUDFRONT.PR.6]: Require an Amazon CloudFront distribution to use custom SSL/TLS certificates',
+        ruleMetadata: {
+          DocumentationUrl: 'https://docs.aws.amazon.com/controltower/latest/userguide/amazon_s3-rules.html#s3-rule-description',
+        },
+        fix: "[FIX]: Provide a 'ViewerCertificate' configuration with values for 'AcmCertificateArn', 'MinimumProtocolVersion', and 'SslSupportMethod'.",
+        ruleName: 'cloudfront_custom_ssl_certificate_check',
+        violatingResources: [
+          {
+            resourceLogicalId: 'DistributionCFDistribution882A7313',
+            templatePath: './tmp',
+            locations: [
+              '/Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate/CloudFrontDefaultCertificate',
+              '/Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate',
+            ],
+          },
+        ],
+      }],
+    });
+  });
+
   test('guard fails', () => {
     // GIVEN
     const validator = new plugin.CfnGuardValidator();
diff --git a/test/rules/control-tower/s3/ct-s3-pr-8.test.ts b/test/rules/control-tower/s3/ct-s3-pr-8.test.ts
index 315d250..62e45a1 100644
--- a/test/rules/control-tower/s3/ct-s3-pr-8.test.ts
+++ b/test/rules/control-tower/s3/ct-s3-pr-8.test.ts
@@ -72,7 +72,7 @@ describe('CT.S3.PR.8', () => {
 
     const report = JSON.parse(fs.readFileSync(path.join(app.outdir, 'policy-validation-report.json')).toString('utf-8').trim());
     const rules = report.pluginReports.flatMap((r: any) => r.violations.flatMap((v: any) => v.ruleName));
-    expect(rules).not.toContain(
+    expect(rules).toContain(
       GUARD_RULE_CHECK_NAME,
     );
   });
@@ -144,4 +144,4 @@ describe('CT.S3.PR.8', () => {
       GUARD_RULE_CHECK_NAME,
     );
   });
-});
\ No newline at end of file
+});
diff --git a/test/test-data/guard-disjunction-resolved-check.json b/test/test-data/guard-disjunction-resolved-check.json
new file mode 100644
index 0000000..fa5c077
--- /dev/null
+++ b/test/test-data/guard-disjunction-resolved-check.json
@@ -0,0 +1,101 @@
+{
+      "name": "",
+      "metadata": {},
+      "status": "FAIL",
+      "not_compliant": [
+        {
+          "Rule": {
+            "name": "cloudfront_custom_ssl_certificate_check",
+            "metadata": {},
+            "messages": {
+              "custom_message": null,
+              "error_message": null
+            },
+            "checks": [
+              {
+                "Rule": {
+                  "name": "check",
+                  "metadata": {},
+                  "messages": {
+                    "custom_message": "\n        [CT.CLOUDFRONT.PR.6]: Require an Amazon CloudFront distribution to use custom SSL/TLS certificates\n            [FIX]: Provide a 'ViewerCertificate' configuration with values for 'AcmCertificateArn', 'MinimumProtocolVersion', and 'SslSupportMethod'.\n        ",
+                    "error_message": null
+                  },
+                  "checks": [
+                    {
+                      "Disjunctions": {
+                        "checks": [
+                          {
+                            "Clause": {
+                              "Unary": {
+                                "context": " CloudFrontDefaultCertificate not EXISTS  ",
+                                "messages": {
+                                  "custom_message": "",
+                                  "error_message": "Check was not compliant as property [/Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate/CloudFrontDefaultCertificate[L:295,C:38]] existed."
+                                },
+                                "check": {
+                                  "Resolved": {
+                                    "value": {
+                                      "path": "/Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate/CloudFrontDefaultCertificate",
+                                      "value": true
+                                    },
+                                    "comparison": [
+                                      "Exists",
+                                      true
+                                    ]
+                                  }
+                                }
+                              }
+                            }
+                          }
+                        ]
+                      }
+                    },
+                    {
+                      "Disjunctions": {
+                        "checks": [
+                          {
+                            "Rule": {
+                              "name": "check_custom_acm_certificate_provided",
+                              "metadata": {},
+                              "messages": {
+                                "custom_message": null,
+                                "error_message": null
+                              },
+                              "checks": [
+                                {
+                                  "Block": {
+                                    "context": "GuardBlockAccessClause#Location[file:ct-cloudfront-pr-6.guard, line:114, column:5]",
+                                    "messages": {
+                                      "custom_message": "",
+                                      "error_message": "Check was not compliant as property [AcmCertificateArn] is missing. Value traversed to [Path=/Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate[L:294,C:26] Value={\"CloudFrontDefaultCertificate\":true}]"
+                                    },
+                                    "unresolved": {
+                                      "traversed_to": {
+                                        "path": "/Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate",
+                                        "value": {
+                                          "CloudFrontDefaultCertificate": true
+                                        }
+                                      },
+                                      "remaining_query": "AcmCertificateArn",
+                                      "reason": "Could not find key AcmCertificateArn inside struct at path /Resources/DistributionCFDistribution882A7313/Properties/DistributionConfig/ViewerCertificate[L:294,C:26]"
+                                    }
+                                  }
+                                }
+                              ]
+                            }
+                          }
+                        ]
+                      }
+                    }
+                  ]
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "not_applicable": [
+        "cloudfront_custom_ssl_certificate_check"
+      ],
+      "compliant": []
+    }