T09 · Insecure Skill Coding Practices
- Location
references/workflows/discovery-and-analysis.md:55- Finding
Terraform State Secrets May Be Persisted in Plaintext Migration Reports
- Content
View full analysis
Vulnerability Details
File Location:
references/workflows/discovery-and-analysis.md, lines 55-64, 120-128, 235, and 242-274
Vulnerability Type: Sensitive data exposure through insufficient redaction
Risk Level: HighVulnerable Code Snippet
markdown Scan all `.tf` and `.tfstate` files, extract every resource definition with complete configuration. | Field | Description | Resolution | |---|---|---| | `id` | Resource identifier | `aws_instance.web`, `data.aws_iam_policy_document.x` | | `type` | Resource type | `aws_instance`, `aws_vpc` | | `discovery_method` | How the resource was found | See table below | | `source_file` | File path where defined | `main.tf`, `modules/vpc/main.tf` | | `region` | From provider config | Explicit `provider = aws.alias` → alias region; else default provider region | | `properties` | Resolved attribute values | Priority: `.tfstate` attrs → `.tfvars` → non-sensitive variable defaults → preserve `var.<name>` | | `dependencies` | Resource IDs this depends on | See dependency detection below |The state-priority and persistence behavior is reinforced later:
markdown `.tf` ∪ `.tfstate` → no duplicates. When both exist for same resource, `.tfstate` values take priority.markdown Write a single JSON object to `.migration-report/input-resources.json`.The variable-handling rules only protect values whose source variable is explicitly marked sensitive:
markdown Rules: 1. Resolve variables from `.tfvars` or defaults when a concrete value is available and safe to copy. 2. If a concrete value cannot be resolved, preserve resource properties as `var.<name>` and record the variable in `variables`. 3. If the source variable declares `sensitive = true`, record `sensitive: true` and propagate that flag to target Terraform variables. 4. If the source variable has no default, record `has_default: false`; missing values are not a d ...[truncated 3180 chars]- Remediation
View remediation
Remediation Suggestions
-
Do not copy complete state attributes by default.
- Extract only attributes explicitly required for resource mapping.
- Maintain per-resource allowlists of migration-relevant, non-secret fields.
-
Redact known sensitive attributes.
- Remove values for fields such as
password,secret,token,private_key,access_key,connection_string,client_secret, and similar provider-specific attributes. - Apply case-insensitive matching to nested object keys.
- Remove values for fields such as
-
Detect credential-like values independently of Terraform metadata.
- Scan values for private-key headers, access-key formats, bearer tokens, signed URLs, and high-entropy credential strings.
- Replace detected values with a structured marker such as:
json { "value": null, "sensitive": true, "source": "redacted_from_state" }
-
Treat state-derived sensitivity conservatively.
- Do not rely only on
variable.sensitive. - Consider provider-returned sensitive fields and unknown state fields sensitive unless an allowlist marks them safe.
- Do not rely only on
-
Preserve references instead of concrete secrets.
- Generate sensitive Terraform variables without defaults.
- Use secret-manager references where appropriate.
- Never request, display, or persist the underlying value in migration reports.
-
Protect generated artifacts.
- Create
.migration-report/with restrictive filesystem permissions. - Add
.migration-report/to.gitignore. - Warn users not to commit, upload, or share reports until they have been reviewed for sensitive data.
- Create
-
Add a mandatory pre-write security check.
- Scan the complete output object before writing
input-resources.json. - Abort or redact automatically if potential credentials are found.
- Record only the field name and redaction reason, never the original value.
- Scan the complete output object before writing
-
**Mini ...[truncated 180 chars]
-
