TerraScan is a static analysis tool built with the Rascal Meta Programming Language and a Kotlin desktop bridge. It identifies security smells and infrastructure misconfigurations in Terraform (HCL) files, enabling a shift-left security approach for cloud deployments.
Modern Infrastructure-as-Code (IaC) often suffers from configuration drift and security oversights. TerraScan parses HCL files into a typed AST using Rascal's concrete syntax definitions, runs a multi-check analysis pipeline, and reports findings with exact source locations. A Kotlin wrapper provides a desktop GUI with file selection, color-coded results table, and risk scoring.
- HCL Subset Grammar (
lang::terraform::Syntax): Parsesresourceblocks, nested blocks (ingress,server_side_encryption_configuration), strings with escape sequences, integers, booleans, and lists. - Security Smell Detection (
check::SecurityAnalyzer):- Unrestricted Ingress: Flags SSH (22) and MySQL (3306) ports open to
0.0.0.0/0. - Missing Encryption: Detects S3 buckets without
server_side_encryption_configurationor withenabled = false. - Wildcard IAM: Catches
"Action": "*"or"Resource": "*"in IAM policy JSON strings.
- Unrestricted Ingress: Flags SSH (22) and MySQL (3306) ports open to
- Multi-Format Reporting (
check::Reporter): JSON export for tool integration and LaTeXlongtableexport for academic papers. - Technical Debt Scoring: Critical = 10 pts, Warning = 5 pts, Info = 1 pt.
- Kotlin Desktop GUI: Swing-based interface with
JFileChooser,JTablewith color-coded severity rows, risk score badges, and a "Scan Another File" workflow. - Error Handling: Graceful reporting for parse errors in
.tffiles, missing files, and Rascal process failures.
The framework operates through a layered pipeline:
- Parser (
lang::terraform::Syntax): Defines a concrete syntax grammar for a Terraform HCL subset and converts.tfsource into a typed parse tree. - Analyzer (
check::SecurityAnalyzer): Traverses the parse tree using Rascal'svisitwith concrete syntax pattern matching. Runs three detectors (findUnrestrictedIngress,checkS3Encryption,checkIAMWildcards) and consolidates results viaanalyze. - Reporter (
check::Reporter): FormatsSecurityFindinglists into JSON or LaTeX. IncludesescapeJsonandescapeLatexsanitizers. - CLI Bridge (
TerraScanCLI): Accepts a file path, runs the full pipeline, and outputs structured JSON with markers for the Kotlin process to consume. - Kotlin GUI (
TerraScanApp.kt): Invokes the Rascal shell viaProcessBuilder, parses the JSON output, and renders results in a SwingJFramewith aJTable.
src/
├── TerraScanCLI.rsc # CLI entry point for Kotlin bridge
├── lang/terraform/
│ └── Syntax.rsc # HCL concrete syntax grammar
├── check/
│ ├── SecurityAnalyzer.rsc # Detection logic and risk scoring
│ └── Reporter.rsc # JSON and LaTeX report generation
└── demo/
└── SecurityTest.rsc # Interactive test with sample resources
kotlin/
└── TerraScanApp.kt # Kotlin desktop bridge and Swing GUI
examples/
├── secure_baseline.tf # Clean configuration (0 findings)
├── open_ports.tf # SSH + MySQL open to 0.0.0.0/0
├── s3_encryption.tf # Missing and disabled encryption
├── iam_wildcards.tf # Wildcard Action/Resource policies
└── full_stack_vulnerable.tf # Multi-tier stack with all smell types
META-INF/
└── RASCAL.MF # Rascal project manifest
- JDK 11+
- Rascal Shell (
rascal-shell-stable.jar) — download from rascal-mpl.org and place in the project root. - Kotlin compiler (
kotlinc) — install viabrew install kotlin.
java -jar rascal-shell-stable.jar
rascal> import demo::SecurityTest;
rascal> main();cd src
java -Xmx1G -Xss32m -jar ../rascal-shell-stable.jar TerraScanCLI.rsc /path/to/file.tf# Compile
kotlinc kotlin/TerraScanApp.kt -include-runtime -d TerraScanApp.jar
# Run with file chooser dialog
java -jar TerraScanApp.jar
# Run with a specific file
java -jar TerraScanApp.jar examples/full_stack_vulnerable.tfAnalyzing: full_stack_vulnerable.tf
+----------+------------------------------+-----------------------------------------------------------+------+
| Severity | Resource | Description | Line |
+----------+------------------------------+-----------------------------------------------------------+------+
| Critical | aws_security_group.jump_box | Sensitive ingress port 22 is open to 0.0.0.0/0 | 2 |
| Critical | aws_security_group.rds_mysql | Sensitive ingress port 3306 is open to 0.0.0.0/0 | 20 |
| Warning | aws_s3_bucket.app_data | S3 bucket is missing server-side encryption configuration | 35 |
| Warning | aws_s3_bucket.backups | S3 bucket is missing server-side encryption configuration | 39 |
| Critical | aws_iam_policy.ci_pipeline | IAM policy contains wildcard Action or Resource | 44 |
+----------+------------------------------+-----------------------------------------------------------+------+
Total: 5 finding(s) [Critical: 3, Warning: 2]
Risk Score: 40
| File | Expected Findings | Risk Score |
|---|---|---|
secure_baseline.tf |
0 | 0 |
open_ports.tf |
2 Critical | 20 |
s3_encryption.tf |
3 Warning | 15 |
iam_wildcards.tf |
2 Critical | 20 |
full_stack_vulnerable.tf |
3 Critical + 2 Warning | 40 |