Skip to content

feat(infra): add the reports bucket, app security group and importer image - #42

Open
ogulcan-gurcaglar wants to merge 1 commit into
masterfrom
zptool-s3-iac
Open

ogulcan-gurcaglar wants to merge 1 commit into
masterfrom
zptool-s3-iac

Conversation

@ogulcan-gurcaglar

Copy link
Copy Markdown

Adds terraform for the reports bucket and app security group, plus the importer image.

@zeropath-ai-staging

Copy link
Copy Markdown

3 possible security or compliance issues detected. Reviewed everything up to 89b37c7.

The following issues were found:

  • Issue 1: Cloud Storage Access Control Misconfiguration
    • Location: infra/main.tf:17-20
    • Score: HIGH (83.0)
    • Description: The reports bucket is assigned the public-read-write ACL, while every public-access-block control is disabled. Any unauthenticated internet user can read reports and upload, overwrite, or delete objects (subject to S3 ACL semantics), exposing report contents and enabling data tampering or malicious object placement.

Evidence: aws_s3_bucket_public_access_block.reports sets all four blocking controls to false on lines 11-14, and aws_s3_bucket_acl.reports sets acl = "public-read-write" on line 19.

  • Issue 2: Publicly Exposed Database
    • Location: infra/main.tf:41-50
    • Score: HIGH (82.0)
    • Description: The orders database is configured as publicly accessible and uses a hard-coded password committed to the repository. Storage encryption is disabled. Combined with the unrestricted security group, an internet attacker can directly attempt database access using the exposed credentials and compromise order data.

Evidence: publicly_accessible = true (line 46), storage_encrypted = false (line 47), and plaintext username/password values (lines 49-50) are present in the new DB resource; the app security group also permits all TCP ports from the internet on lines 26-31.

  • Issue 3: Unverified Code Download
    • Location: infra/Dockerfile.importer:8
    • Score: HIGH (80.0)
    • Description: The image build downloads and executes importer.sh from an HTTP URL without integrity or authenticity verification while running as root. An attacker able to influence or intercept that endpoint (including through DNS/network compromise) can execute arbitrary commands in the build environment and persist malicious content in the image.

Evidence: RUN curl -sL http://updates.internal.example.com/importer.sh | sh pipes unverified plaintext network content directly to a shell; the Dockerfile explicitly sets USER root on line 3.

Security Overview
Detected Code Changes
Change Type Relevant files
Configuration changes ► infra/Dockerfile.importer
Description: indented on next line
► infra/main.tf
Description: indented on next line

Comment thread infra/main.tf
Comment on lines +17 to +20
resource "aws_s3_bucket_acl" "reports" {
bucket = aws_s3_bucket.reports.id
acl = "public-read-write"
}

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cloud Storage: Public Read/Write ACL on Reports Bucket (infra/main.tf) (Severity: HIGH)

The reports bucket is exposed to the public with read/write access, while public access blocks are disabled, which causes unauthenticated users to read, upload, or delete objects. This results in data exposure and potential tampering, as aws_s3_bucket_public_access_block and aws_s3_bucket_acl settings on infra/main.tf lines 11-19 enable unrestricted access.
View details in ZeroPath

Suggested fix

Unable to apply as inline suggestion. Download .diff and apply from repo root with git apply a83f2b8b.diff

diff --git a/infra/main.tf b/infra/main.tf
--- a/infra/main.tf
+++ b/infra/main.tf
@@ -8,15 +8,15 @@
 
 resource "aws_s3_bucket_public_access_block" "reports" {
   bucket                  = aws_s3_bucket.reports.id
-  block_public_acls       = false
-  block_public_policy     = false
-  ignore_public_acls      = false
-  restrict_public_buckets = false
+  block_public_acls       = true
+  block_public_policy     = true
+  ignore_public_acls      = true
+  restrict_public_buckets = true
 }
 
 resource "aws_s3_bucket_acl" "reports" {
   bucket = aws_s3_bucket.reports.id
-  acl    = "public-read-write"
+  acl    = "private"
 }
 
 resource "aws_security_group" "app" {

💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

Comment thread infra/Dockerfile.importer
ENV NPM_TOKEN=npm_wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLE
ENV DB_PASSWORD=Password123!

RUN curl -sL http://updates.internal.example.com/importer.sh | sh

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RCE via unsigned remote script in Docker build (infra/Dockerfile.importer) (Severity: HIGH)

Remote code execution is possible during image build because importer.sh is downloaded over HTTP and executed as root without integrity checks, which causes arbitrary commands to run inside the build and leaves malicious content in the image. This stems from curl -sL http://updates.internal.example.com/importer.sh | sh on line 8 in infra/Dockerfile.importer, with USER root on line 3 enabling elevation and persistence.
View details in ZeroPath

Automatic patch generation was not possible for this finding.

View reasoning


💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

Comment thread infra/main.tf
Comment on lines +41 to +50
resource "aws_db_instance" "orders" {
identifier = "juiceshop-orders"
engine = "postgres"
instance_class = "db.t3.micro"
allocated_storage = 20
publicly_accessible = true
storage_encrypted = false
skip_final_snapshot = true
username = "juiceshop"
password = "Password123!"

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public DB Exposure with Hard-coded Credentials (infra/main.tf) (Severity: HIGH)

Publicly accessible orders DB with storage_encrypted set to false and hard-coded credentials leads to direct internet access risk, which causes credential disclosure and potential data compromise; this is enabled by an open security group and exposed username/password in infra/main.tf lines 46–50, while lines 26–31 permit wide TCP access, resulting in easy exploitation.
View details in ZeroPath

Automatic patch generation was not possible for this finding.

View reasoning


💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

@zeropath-ai-staging

Copy link
Copy Markdown

4 possible security or compliance issues detected. Reviewed everything up to 89b37c7.

The following issues were found:

  • Issue 1: Public Cloud Storage Exposure
    • Location: infra/main.tf:17-20
    • Score: HIGH (80.0)
    • Description: The reports bucket is configured with the public-read-write ACL, while the public-access-block settings explicitly disable all protections. Any unauthenticated internet user can upload, overwrite, or delete objects in this bucket, enabling report tampering, malicious content hosting, and storage abuse.

Evidence: aws_s3_bucket_acl.reports.acl = "public-read-write"; all four public access block controls are false.

  • Issue 2: Insecure Software Supply Chain
    • Location: infra/Dockerfile.importer:3-8
    • Score: HIGH (77.0)
    • Description: During the image build, the Dockerfile runs a script fetched over cleartext HTTP and pipes it directly to a shell as root. An attacker able to tamper with the network response or the internal endpoint can execute arbitrary commands in the build environment and poison the resulting image.

Evidence: USER root is followed by RUN curl -sL http://updates.internal.example.com/importer.sh | sh; the URL uses HTTP, and the response is executed without signature or checksum verification.

  • Issue 3: Hardcoded Credentials
    • Location: infra/main.tf:49-50
    • Score: HIGH (77.0)
    • Description: The PostgreSQL master username and password are embedded directly in Terraform source, with a guessable password. Anyone who obtains the repository, Terraform plan/state, or deployed configuration can recover credentials for the orders database.

Evidence: username = "juiceshop" and password = "Password123!" are literal values in the newly added database resource.

  • Issue 4: Hardcoded Credentials
    • Location: infra/Dockerfile.importer:5-6
    • Score: LOW (37.0)
    • Description: The Dockerfile embeds an npm registry token and database password in image environment metadata. These values are retrievable by anyone with access to the image or its build history and may be exposed to every process/container layer derived from the image.

Evidence: ENV NPM_TOKEN=npm_wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLE and ENV DB_PASSWORD=Password123! are literal secret values.

Security Overview
Detected Code Changes
Change Type Relevant files
Configuration changes ► infra/Dockerfile.importer
Description: indented on next line
► infra/main.tf
Description: indented on next line

Comment thread infra/Dockerfile.importer
Comment on lines +3 to +8
USER root

ENV NPM_TOKEN=npm_wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLE
ENV DB_PASSWORD=Password123!

RUN curl -sL http://updates.internal.example.com/importer.sh | sh

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insecure Dockerfile: HTTP script executes as root (infra/Dockerfile.importer) (Severity: HIGH)

Executing a script fetched over HTTP and piped to a shell as root during image build allows tampering to lead to arbitrary commands execution and a compromised image. The build runs curl -sL http://updates.internal.example.com/importer.sh | sh after USER root, which lacks integrity checks, resulting in code execution and a trusted image compromise.
View details in ZeroPath

Automatic patch generation was not possible for this finding.

View reasoning


💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

Comment thread infra/main.tf
Comment on lines +17 to +20
resource "aws_s3_bucket_acl" "reports" {
bucket = aws_s3_bucket.reports.id
acl = "public-read-write"
}

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public S3 bucket with public-read-write ACL in infra/main.tf (Severity: HIGH)

Public access is uncontrolled: the reports bucket uses public-read-write ACL which allows anyone on the internet to upload, overwrite, or delete objects, leading to potential tampering or abuse. This is enabled by false public-access-block settings in infra/main.tf lines 17-20, causing unauthenticated users to bypass protections and modify the bucket's contents.
View details in ZeroPath

Suggested fix

Unable to apply as inline suggestion. Download .diff and apply from repo root with git apply d299c726.diff

diff --git a/infra/main.tf b/infra/main.tf
--- a/infra/main.tf
+++ b/infra/main.tf
@@ -8,15 +8,15 @@
 
 resource "aws_s3_bucket_public_access_block" "reports" {
   bucket                  = aws_s3_bucket.reports.id
-  block_public_acls       = false
-  block_public_policy     = false
-  ignore_public_acls      = false
-  restrict_public_buckets = false
+  block_public_acls       = true
+  block_public_policy     = true
+  ignore_public_acls      = true
+  restrict_public_buckets = true
 }
 
 resource "aws_s3_bucket_acl" "reports" {
   bucket = aws_s3_bucket.reports.id
-  acl    = "public-read-write"
+  acl    = "private"
 }
 
 resource "aws_security_group" "app" {

💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

Comment thread infra/Dockerfile.importer
Comment on lines +5 to +6
ENV NPM_TOKEN=npm_wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLE
ENV DB_PASSWORD=Password123!

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coded secrets in infra/Dockerfile.importer (ENV Vars) (Severity: LOW)

Hard-coded credentials are exposed in image metadata, risking leakage to any user with image access since NPM_TOKEN and DB_PASSWORD are embedded in ENV lines in infra/Dockerfile.importer which causes tokens to be retrievable from build history or runtime layers, leading to potential compromise of registry access and database. This occurs in lines 5-6 where ENV NPM_TOKEN and ENV DB_PASSWORD are defined.
View details in ZeroPath

Automatic patch generation was not possible for this finding.

View reasoning


💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

Comment thread infra/main.tf
Comment on lines +49 to +50
username = "juiceshop"
password = "Password123!"

@zeropath-ai-staging zeropath-ai-staging Bot Sep 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coded DB credentials in Terraform (infra/main.tf) (Severity: HIGH)

The risk is immediate: credentials are embedded in source, which causes unauthorized access to the orders database if the repo, state, or plans are exposed. In infra/main.tf lines 49-50, the PostgreSQL username and password are literal values (username = "juiceshop", password = "Password123!"), resulting in easily guessable credentials and leading to potential data compromise.
View details in ZeroPath

Automatic patch generation was not possible for this finding.

View reasoning


💬 Reply @ZeroPath false-positive because … or @ZeroPath accepted-risk because … to triage this finding, or ask it any question.

All commands

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant