|
| 1 | +# Lab 6 — Submission |
| 2 | + |
| 3 | +## Task 1: Checkov on Terraform + Pulumi |
| 4 | + |
| 5 | +> **Note on lab issues:** |
| 6 | +> 1. Checkov 3.x outputs JSON arrays, not objects. The provided `jq` commands fail with `Cannot index array with string "results"`. Fixed by using `jq '[.[] | ...]'`. |
| 7 | +> 2. The Checkov open-source version does not populate the `severity` field (returns `null`), so the Severity table cannot be filled. |
| 8 | +> 3. Task 1 lacks Pulumi commands, and the `pulumi-state-rendered.json` fallback file is missing from the repository, making the Pulumi scan impossible here. |
| 9 | +
|
| 10 | +### Terraform scan |
| 11 | +- Total checks: 129 |
| 12 | +- Passed: 49 |
| 13 | +- Failed: 80 |
| 14 | + |
| 15 | +| Severity | Count | |
| 16 | +|----------|------:| |
| 17 | +| Critical | N/A (null) | |
| 18 | +| High | N/A (null) | |
| 19 | +| Medium | N/A (null) | |
| 20 | +| Low | N/A (null) | |
| 21 | + |
| 22 | +### Top 5 rule IDs (by frequency) |
| 23 | +| Rule ID | Count | What it checks | |
| 24 | +|---------|------:|----------------| |
| 25 | +| CKV_AWS_289 | 4 | Ensure IAM policies does not allow permissions management / resource exposure without constraints | |
| 26 | +| CKV_AWS_355 | 4 | Ensure no IAM policies documents allow "*" as a statement's resource for restrictable actions | |
| 27 | +| CKV_AWS_23 | 3 | Ensure every security group and rule has a description | |
| 28 | +| CKV_AWS_288 | 3 | Ensure IAM policies does not allow data exfiltration | |
| 29 | +| CKV_AWS_290 | 3 | Ensure IAM policies does not allow write access without constraints | |
| 30 | + |
| 31 | +### Pulumi scan |
| 32 | +| Severity | Count | |
| 33 | +|----------|------:| |
| 34 | +| N/A | N/A | |
| 35 | + |
| 36 | +*(Pulumi Checkov scan skipped due to missing `pulumi-state-rendered.json` and lack of native Pulumi source support in Checkov 3.x).* |
| 37 | + |
| 38 | +### Module-leverage analysis (Lecture 6 slide 17) |
| 39 | +Looking at the top-5 Terraform rules, 4 of them (CKV_AWS_289, CKV_AWS_355, CKV_AWS_288, CKV_AWS_290) are related to overly permissive IAM policies. If the base IAM policy module restricted the use of wildcards (`*`) for resources and actions by default, this single fix would immediately resolve 14 vulnerabilities. |
| 40 | + |
| 41 | + |
| 42 | +## Task 2: KICS on Ansible |
| 43 | + |
| 44 | +> **Note on lab issues:** |
| 45 | +> The `jq` commands provided in the instructions attempt to read from `labs/lab6/results/kics/results.json`. However, the Docker commands output the results to `results/kics-ansible/` and `results/kics-pulumi/`. The `jq` path had to be corrected to point to `kics-ansible/results.json` to work. |
| 46 | +
|
| 47 | +### Severity breakdown (Ansible) |
| 48 | +| Severity | Count | |
| 49 | +|----------|------:| |
| 50 | +| HIGH | 3 | |
| 51 | +| MEDIUM | 0 | |
| 52 | +| LOW | 1 | |
| 53 | +| INFO | 0 | |
| 54 | +*(Note: This counts unique triggered rules based on the lab's `jq` query. The total number of affected files/findings is 9 High and 1 Low).* |
| 55 | + |
| 56 | +### Top 5 KICS queries (by frequency) |
| 57 | +| Query | Severity | Files | |
| 58 | +|-------|----------|------:| |
| 59 | +| Passwords And Secrets - Generic Password | HIGH | 6 | |
| 60 | +| Passwords And Secrets - Password in URL | HIGH | 2 | |
| 61 | +| Passwords And Secrets - Generic Secret | HIGH | 1 | |
| 62 | +| Unpinned Package Version | LOW | 1 | |
| 63 | + |
| 64 | + |
| 65 | +### Checkov vs KICS — when to use which? (Lecture 6 slide 10) |
| 66 | +- **One thing Checkov did better for the Terraform sample:** Checkov has deep, native understanding of AWS architectures and provides specialized, graph-based rules (like cross-resource checks for IAM), making it incredibly powerful for cloud-native IaC like Terraform. |
| 67 | +- **One thing KICS did better for the Ansible sample:** KICS natively parsed Ansible playbooks and Pulumi YAML configurations without needing state translation, effectively finding hardcoded secrets and unpinned packages in configuration management tools where Checkov struggles or requires workarounds. |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## Bonus: Custom Checkov Policy |
| 72 | + |
| 73 | +### Policy file |
| 74 | +```yaml |
| 75 | +metadata: |
| 76 | + name: "Ensure RDS instances have deletion protection enabled" |
| 77 | + id: "CKV2_CUSTOM_1" |
| 78 | + category: "BACKUP_AND_RECOVERY" |
| 79 | + severity: "HIGH" |
| 80 | +definition: |
| 81 | + cond_type: "attribute" |
| 82 | + resource_types: |
| 83 | + - "aws_db_instance" |
| 84 | + attribute: "deletion_protection" |
| 85 | + operator: "equals" |
| 86 | + value: true |
| 87 | +``` |
| 88 | +
|
| 89 | +### Rule fires |
| 90 | +Output of `jq '.[] | .results.failed_checks[]? | select(.check_id | startswith("CKV2_CUSTOM_"))'`: |
| 91 | +```json |
| 92 | +{ |
| 93 | + "check_id": "CKV2_CUSTOM_1", |
| 94 | + "bc_check_id": null, |
| 95 | + "check_name": "Ensure RDS instances have deletion protection enabled", |
| 96 | + "check_result": { |
| 97 | + "result": "FAILED", |
| 98 | + "entity": { |
| 99 | + "aws_db_instance": { |
| 100 | + "weak_db": { ... } |
| 101 | + } |
| 102 | + } |
| 103 | + }, |
| 104 | + "resource": "aws_db_instance.weak_db", |
| 105 | + "severity": "HIGH" |
| 106 | +} |
| 107 | +``` |
| 108 | +*(Note: JSON output truncated for readability. It successfully fired on both `aws_db_instance.unencrypted_db` and `aws_db_instance.weak_db`).* |
| 109 | + |
| 110 | +### Why this rule matters |
| 111 | +This custom policy prevents accidental or malicious deletion of production databases by enforcing AWS RDS deletion protection. A real-world example of this risk was the GitLab database outage in 2017, where an admin accidentally deleted critical database files; having strict deletion protection controls enforced at the IaC level adds a necessary layer of defense against irrecoverable data loss and helps comply with standard availability frameworks like SOC2. |
| 112 | + |
0 commit comments