-
Notifications
You must be signed in to change notification settings - Fork 8
Preview/Trivy #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Preview/Trivy #91
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| reviews: | ||
| tools: | ||
| checkov: | ||
| enabled: false | ||
| hadolint: | ||
| enabled: false | ||
| gitleaks: | ||
| enabled: false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| FROM ubuntu:18.04 | ||
|
|
||
| ENV DEBIAN_FRONTEND=noninteractive | ||
|
|
||
| RUN apt-get update && apt-get install -y \ | ||
| curl \ | ||
| wget \ | ||
| python3 \ | ||
| python3-pip \ | ||
| openssh-server | ||
|
Comment on lines
+5
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Container runs as root and includes SSH server. No Consider:
🛡️ Proposed fixes RUN apt-get update && apt-get install -y \
+ --no-install-recommends \
curl \
wget \
python3 \
- python3-pip \
- openssh-server
+ python3-pip \
+ && rm -rf /var/lib/apt/lists/*
+RUN useradd -r -u 1000 appuser
+
# ... other instructions ...
+USER appuser
+
-EXPOSE 22 80 443
+EXPOSE 80 443Also applies to: 22-24 🧰 Tools🪛 Trivy (0.69.3)[error] 5-10: 'apt-get' missing '--no-install-recommends' '--no-install-recommends' flag is missed: 'apt-get update && apt-get install -y curl wget python3 python3-pip openssh-server' Rule: DS-0029 (IaC/Dockerfile) 🤖 Prompt for AI Agents |
||
|
|
||
| ADD https://example.com/installer/demoapp-bundle.tar.gz /tmp/bundle.tar.gz | ||
|
|
||
| RUN tar -xzf /tmp/bundle.tar.gz -C /opt | ||
|
Comment on lines
+12
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Using
Prefer downloading with ✅ Proposed fix with checksum verification-ADD https://example.com/installer/demoapp-bundle.tar.gz /tmp/bundle.tar.gz
-
-RUN tar -xzf /tmp/bundle.tar.gz -C /opt
+RUN curl -fsSL -o /tmp/bundle.tar.gz https://example.com/installer/demoapp-bundle.tar.gz \
+ && echo "EXPECTED_SHA256 /tmp/bundle.tar.gz" | sha256sum -c - \
+ && tar -xzf /tmp/bundle.tar.gz -C /opt \
+ && rm /tmp/bundle.tar.gz🤖 Prompt for AI Agents |
||
|
|
||
| COPY . /app | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| RUN pip3 install -r requirements.txt | ||
|
|
||
| EXPOSE 22 80 443 | ||
|
|
||
| CMD ["python3", "/app/server.py"] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||||||||||||
| FROM ubuntu:latest | ||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Container runs as root and exposes SSH port. The Dockerfile lacks a 🛡️ Proposed fix for non-root user FROM ubuntu:latest
+RUN useradd -r -u 1000 -g root appuser
+
# ... other instructions ...
+USER appuser
+
CMD ["/app/legacy-agent"]Also consider whether SSH exposure is necessary, or if exec-based access ( Also applies to: 11-11 🧰 Tools🪛 Trivy (0.69.3)[error] 1-1: Image user should not be 'root' Specify at least 1 USER command in Dockerfile with non-root user as argument Rule: DS-0002 (IaC/Dockerfile) 🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| ENV API_TOKEN=internal_token_2c8b41d9c0a64e1e9b0f3e7a1d5c8b41 | ||||||||||||||||
| ENV AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE | ||||||||||||||||
| ENV AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY | ||||||||||||||||
|
Comment on lines
+3
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Credentials baked into Docker image layers are permanently exposed. Environment variables set via Secrets should be injected at runtime via:
🔐 Proposed fix removing baked-in credentials FROM ubuntu:latest
-ENV API_TOKEN=internal_token_2c8b41d9c0a64e1e9b0f3e7a1d5c8b41
-ENV AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
-ENV AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+# Secrets should be injected at runtime, not baked into image
+# Example: docker run -e API_TOKEN=$API_TOKEN -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID ...📝 Committable suggestion
Suggested change
🧰 Tools🪛 Trivy (0.69.3)[error] 3-3: Secrets passed via Possible exposure of secret env "API_TOKEN" in ENV Rule: DS-0031 (IaC/Dockerfile) [error] 4-4: Secrets passed via Possible exposure of secret env "AWS_ACCESS_KEY_ID" in ENV Rule: DS-0031 (IaC/Dockerfile) [error] 5-5: Secrets passed via Possible exposure of secret env "AWS_SECRET_ACCESS_KEY" in ENV Rule: DS-0031 (IaC/Dockerfile) 🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| RUN apt-get update && apt-get install -y curl | ||||||||||||||||
|
|
||||||||||||||||
| COPY . /app | ||||||||||||||||
|
|
||||||||||||||||
| EXPOSE 22 | ||||||||||||||||
|
|
||||||||||||||||
| CMD ["/app/legacy-agent"] | ||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,51 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_iam_policy" "wildcard_admin" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = "demoapp-wildcard-admin" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = "Broad admin policy for demoapp service workers" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| policy = jsonencode({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Version = "2012-10-17" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Statement = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Effect = "Allow" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action = "*" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Resource = "*" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Effect = "Allow" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action = ["s3:*", "iam:PassRole", "kms:Decrypt"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Resource = "*" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+5
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: IAM policy grants unrestricted The policy allows all actions on all resources, violating the principle of least privilege. The second statement with Scope permissions to specific actions and resources required by the service. 🔒 Example of scoped policy policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
- Action = "*"
- Resource = "*"
- },
- {
- Effect = "Allow"
- Action = ["s3:*", "iam:PassRole", "kms:Decrypt"]
- Resource = "*"
+ Action = [
+ "s3:GetObject",
+ "s3:PutObject",
+ "s3:ListBucket"
+ ]
+ Resource = [
+ "arn:aws:s3:::demoapp-artifacts-prod",
+ "arn:aws:s3:::demoapp-artifacts-prod/*"
+ ]
}
]
})📝 Committable suggestion
Suggested change
🧰 Tools🪛 Trivy (0.69.3)[error] 5-19: Disallow unrestricted S3 IAM Policies IAM policy allows 's3:*' action Rule: AWS-0345 Resource: (IaC/AWS) [error] 5-19: Disallow unrestricted S3 IAM Policies IAM role uses a policy that allows 's3:*' action Rule: AWS-0345 Resource: (IaC/AWS) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_iam_role" "service" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = "demoapp-service-role" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assume_role_policy = jsonencode({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Version = "2012-10-17" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Statement = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Effect = "Allow" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Principal = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AWS = "*" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Action = "sts:AssumeRole" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Assume role policy allows any AWS account to assume this role. Setting Restrict the principal to specific trusted accounts, services, or roles. 🔒 Proposed fix with scoped trust policy assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
- AWS = "*"
+ Service = "ec2.amazonaws.com" # Or specific account/role ARN
}
Action = "sts:AssumeRole"
+ Condition = {
+ StringEquals = {
+ "aws:SourceAccount" = "123456789012"
+ }
+ }
}
]
})📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_iam_role_policy_attachment" "service_admin" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| role = aws_iam_role.service.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| policy_arn = aws_iam_policy.wildcard_admin.arn | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_iam_user" "ci" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = "demoapp-ci" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_iam_user_policy_attachment" "ci_admin" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user = aws_iam_user.ci.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+44
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CI user granted CI/CD pipelines typically need limited permissions (e.g., deploy to specific services, push to ECR). Full administrator access allows the CI user to modify IAM, create resources, access secrets, and potentially escalate privileges if credentials leak. Create a scoped policy with only the permissions required for CI operations. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| terraform { | ||||||||||||||||||||||||||||||||||||||||||||
| required_version = ">= 1.5" | ||||||||||||||||||||||||||||||||||||||||||||
| required_providers { | ||||||||||||||||||||||||||||||||||||||||||||
| aws = { | ||||||||||||||||||||||||||||||||||||||||||||
| source = "hashicorp/aws" | ||||||||||||||||||||||||||||||||||||||||||||
| version = "~> 5.0" | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| provider "aws" { | ||||||||||||||||||||||||||||||||||||||||||||
| region = "us-east-1" | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_s3_bucket" "artifacts" { | ||||||||||||||||||||||||||||||||||||||||||||
| bucket = "demoapp-artifacts-prod" | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing encryption and public access controls on S3 buckets. Both buckets lack server-side encryption with customer-managed keys (CMK), and the
🔐 Proposed additions for encryption and access controlsresource "aws_kms_key" "s3" {
description = "KMS key for S3 bucket encryption"
deletion_window_in_days = 7
}
resource "aws_s3_bucket_server_side_encryption_configuration" "artifacts" {
bucket = aws_s3_bucket.artifacts.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.s3.arn
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "logs" {
bucket = aws_s3_bucket.logs.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.s3.arn
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_public_access_block" "logs" {
bucket = aws_s3_bucket.logs.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}Also applies to: 33-43 🧰 Tools🪛 Trivy (0.69.3)[error] 15-17: S3 encryption should use Customer Managed Keys Bucket does not encrypt data with a customer managed key. Rule: AWS-0132 Resource: (IaC/AWS) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_s3_bucket_acl" "artifacts" { | ||||||||||||||||||||||||||||||||||||||||||||
| bucket = aws_s3_bucket.artifacts.id | ||||||||||||||||||||||||||||||||||||||||||||
| acl = "public-read" | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_s3_bucket_public_access_block" "artifacts" { | ||||||||||||||||||||||||||||||||||||||||||||
| bucket = aws_s3_bucket.artifacts.id | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| block_public_acls = false | ||||||||||||||||||||||||||||||||||||||||||||
| block_public_policy = false | ||||||||||||||||||||||||||||||||||||||||||||
| ignore_public_acls = false | ||||||||||||||||||||||||||||||||||||||||||||
| restrict_public_buckets = false | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+19
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: S3 bucket configured for public access exposes data to the internet. The If public access is truly required (e.g., static website hosting), consider:
🔒 Proposed fix for secure bucket configuration-resource "aws_s3_bucket_acl" "artifacts" {
- bucket = aws_s3_bucket.artifacts.id
- acl = "public-read"
-}
-
-resource "aws_s3_bucket_public_access_block" "artifacts" {
- bucket = aws_s3_bucket.artifacts.id
-
- block_public_acls = false
- block_public_policy = false
- ignore_public_acls = false
- restrict_public_buckets = false
-}
+resource "aws_s3_bucket_public_access_block" "artifacts" {
+ bucket = aws_s3_bucket.artifacts.id
+
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}📝 Committable suggestion
Suggested change
🧰 Tools🪛 Trivy (0.69.3)[error] 27-27: S3 Access block should block public ACL Public access block does not block public ACLs Rule: AWS-0086 Resource: (IaC/AWS) [error] 28-28: S3 Access block should block public policy Public access block does not block public policies Rule: AWS-0087 Resource: (IaC/AWS) [error] 29-29: S3 Access Block should Ignore Public ACL Public access block does not ignore public ACLs Rule: AWS-0091 Resource: (IaC/AWS) [error] 21-21: S3 Buckets not publicly accessible through ACL. Bucket has a public ACL: "public-read" Rule: AWS-0092 Resource: (IaC/AWS) [error] 30-30: S3 Access block should restrict public bucket to limit access Public access block does not restrict public buckets Rule: AWS-0093 Resource: (IaC/AWS) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_s3_bucket" "logs" { | ||||||||||||||||||||||||||||||||||||||||||||
| bucket = "demoapp-logs-prod" | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_s3_bucket_versioning" "logs" { | ||||||||||||||||||||||||||||||||||||||||||||
| bucket = aws_s3_bucket.logs.id | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| versioning_configuration { | ||||||||||||||||||||||||||||||||||||||||||||
| status = "Disabled" | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,50 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_security_group" "web" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = "demoapp-web" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = "Public web tier security group" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpc_id = "vpc-0123456789abcdef0" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ingress { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = "SSH from anywhere" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from_port = 22 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to_port = 22 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| protocol = "tcp" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cidr_blocks = ["0.0.0.0/0"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ingress { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = "RDP from anywhere" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from_port = 3389 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to_port = 3389 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| protocol = "tcp" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cidr_blocks = ["0.0.0.0/0"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ingress { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description = "All TCP" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from_port = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to_port = 65535 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| protocol = "tcp" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cidr_blocks = ["0.0.0.0/0"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+6
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Security group allows unrestricted inbound access from the internet. The ingress rules permit:
This effectively makes any resource using this security group fully accessible from the internet. Restrict CIDR blocks to known IP ranges or use VPN/bastion access patterns. 🔒 Proposed fix with restricted access ingress {
description = "SSH from anywhere"
from_port = 22
to_port = 22
protocol = "tcp"
- cidr_blocks = ["0.0.0.0/0"]
+ cidr_blocks = ["10.0.0.0/8"] # Internal network only
}
- ingress {
- description = "RDP from anywhere"
- from_port = 3389
- to_port = 3389
- protocol = "tcp"
- cidr_blocks = ["0.0.0.0/0"]
- }
-
- ingress {
- description = "All TCP"
- from_port = 0
- to_port = 65535
- protocol = "tcp"
- cidr_blocks = ["0.0.0.0/0"]
- }
+ # Remove overly permissive rules; add specific ports as needed📝 Committable suggestion
Suggested change
🧰 Tools🪛 Trivy (0.69.3)[error] 11-11: Security groups should not allow unrestricted ingress to SSH or RDP from any IP address. Security group rule allows unrestricted ingress from any IP address. Rule: AWS-0107 Resource: (IaC/AWS) [error] 19-19: Security groups should not allow unrestricted ingress to SSH or RDP from any IP address. Security group rule allows unrestricted ingress from any IP address. Rule: AWS-0107 Resource: (IaC/AWS) [error] 27-27: Security groups should not allow unrestricted ingress to SSH or RDP from any IP address. Security group rule allows unrestricted ingress from any IP address. Rule: AWS-0107 Resource: (IaC/AWS) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| egress { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from_port = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| to_port = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| protocol = "-1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cidr_blocks = ["0.0.0.0/0"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resource "aws_db_instance" "primary" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| identifier = "demoapp-primary" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine = "postgres" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine_version = "14.7" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| instance_class = "db.t3.medium" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allocated_storage = 20 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| username = "demoapp" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| password = "Sup3rS3cr3tP@ssword" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| publicly_accessible = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| storage_encrypted = false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| skip_final_snapshot = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vpc_security_group_ids = [aws_security_group.web.id] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: RDS instance is publicly accessible with unencrypted storage and hardcoded credentials. Multiple security issues:
Combined with the open security group, this database is directly attackable from the internet. 🔐 Proposed secure RDS configuration resource "aws_db_instance" "primary" {
identifier = "demoapp-primary"
engine = "postgres"
engine_version = "14.7"
instance_class = "db.t3.medium"
allocated_storage = 20
- username = "demoapp"
- password = "Sup3rS3cr3tP@ssword"
- publicly_accessible = true
- storage_encrypted = false
+ username = var.db_username
+ manage_master_user_password = true # Uses Secrets Manager
+ publicly_accessible = false
+ storage_encrypted = true
+ kms_key_id = aws_kms_key.rds.arn
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.web.id]
+ db_subnet_group_name = aws_db_subnet_group.private.name
}🧰 Tools🪛 Trivy (0.69.3)[error] 47-47: RDS encryption has not been enabled at a DB Instance level. Instance does not have storage encryption enabled. Rule: AWS-0080 Resource: (IaC/AWS) [error] 46-46: RDS Publicly Accessible Instance has Public Access enabled Rule: AWS-0180 Resource: (IaC/AWS) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||
| provider "aws" { | ||||||||||||||||||||||||
| alias = "deploy" | ||||||||||||||||||||||||
| region = "us-west-2" | ||||||||||||||||||||||||
| access_key = "AKIAIOSFODNN7EXAMPLE" | ||||||||||||||||||||||||
| secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+1
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: AWS credentials hardcoded in provider configuration. Embedding AWS credentials should be provided via:
🔐 Proposed fix removing hardcoded credentials provider "aws" {
alias = "deploy"
region = "us-west-2"
- access_key = "AKIAIOSFODNN7EXAMPLE"
- secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
+ # Credentials provided via environment or instance profile
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| resource "aws_ssm_parameter" "datadog_key" { | ||||||||||||||||||||||||
| name = "/demoapp/observability/datadog_api_key" | ||||||||||||||||||||||||
| type = "String" | ||||||||||||||||||||||||
| value = "1234567890abcdef1234567890abcdef" | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| resource "aws_ssm_parameter" "internal_token" { | ||||||||||||||||||||||||
| name = "/demoapp/internal/service_token" | ||||||||||||||||||||||||
| type = "String" | ||||||||||||||||||||||||
| value = "internal_token_2c8b41d9c0a64e1e9b0f3e7a1d5c8b41" | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+8
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SSM parameters use Storing API keys and tokens with 🔐 Proposed fix using SecureString resource "aws_ssm_parameter" "datadog_key" {
name = "/demoapp/observability/datadog_api_key"
- type = "String"
- value = "1234567890abcdef1234567890abcdef"
+ type = "SecureString"
+ value = var.datadog_api_key # Pass via TF_VAR or secrets manager
}
resource "aws_ssm_parameter" "internal_token" {
name = "/demoapp/internal/service_token"
- type = "String"
- value = "internal_token_2c8b41d9c0a64e1e9b0f3e7a1d5c8b41"
+ type = "SecureString"
+ value = var.internal_token # Pass via TF_VAR or secrets manager
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| resource "aws_db_instance_password" "fallback" { | ||||||||||||||||||||||||
| password = "Sup3rS3cr3tP@ssword" | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: There is no "aws_db_instance_password" resource in the Terraform AWS provider. Extensive searches across official Terraform Registry documentation, GitHub issues, and related resources show no evidence of such a resource existing as of 2026-04-25. Password management for AWS RDS DB instances (aws_db_instance) is handled directly within that resource via attributes like: - password: Plain-text password (stored in state, sensitive). - password_wo: Write-only password (Terraform 1.11+, not stored in state). - manage_master_user_password: Integrates with AWS Secrets Manager for managed passwords (recommended for security). Examples from official docs: resource "aws_db_instance" "example" { username = "foo" password = "foobarbaz" # Or use password_wo or manage_master_user_password # ... } For secure practices, use random_password resource or Secrets Manager integration. No separate resource for just the password exists; it's part of aws_db_instance or aws_rds_cluster. Citations:
Remove Terraform will fail during Current code🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| environment = "production" | ||
| region = "us-east-1" | ||
| db_username = "demoapp" | ||
| db_password = "Sup3rS3cr3tP@ssword" | ||
| admin_api_token = "internal_token_2c8b41d9c0a64e1e9b0f3e7a1d5c8b41" | ||
| private_key_pem = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAyqXmSVk3...truncated...AAAA\n-----END RSA PRIVATE KEY-----" | ||
|
Comment on lines
+1
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Variables defined in tfvars but not declared or consumed. Per the related context, Either remove unused tfvars entries or add proper variable declarations and references. 🤖 Prompt for AI Agents
Comment on lines
+4
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Plaintext secrets committed to version control. This file contains plaintext database password, API token, and RSA private key. Once committed, these secrets persist in git history even if removed later. Production secrets should be:
🔐 Recommended approach using environment variables or data sources# variables.tf
variable "db_password" {
type = string
sensitive = true
}
variable "admin_api_token" {
type = string
sensitive = true
}
# Then set via environment: TF_VAR_db_password, TF_VAR_admin_api_token
# Or use data sources:
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "demoapp/db/password"
}Remove 🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Base image
ubuntu:18.04reached end of life in April 2023.This image no longer receives security updates, leaving the container vulnerable to unpatched CVEs. Upgrade to a supported LTS release.
📦 Proposed base image update
📝 Committable suggestion
🧰 Tools
🪛 Trivy (0.69.3)
[error] 1-1: Image user should not be 'root'
Specify at least 1 USER command in Dockerfile with non-root user as argument
Rule: DS-0002
Learn more
(IaC/Dockerfile)
🤖 Prompt for AI Agents