Skip to content

[security-audit-agent] Security Audit Findings — 2026-06-15#75

Open
rosa-regional-platform-ci wants to merge 1 commit into
openshift-online:mainfrom
rosa-regional-platform-ci:security-audit-2026-06-15
Open

[security-audit-agent] Security Audit Findings — 2026-06-15#75
rosa-regional-platform-ci wants to merge 1 commit into
openshift-online:mainfrom
rosa-regional-platform-ci:security-audit-2026-06-15

Conversation

@rosa-regional-platform-ci

Copy link
Copy Markdown

Security Audit — rosa-regional-platform-cli

Date: 2026-06-15
Auditor: Automated security-audit-agent
Method: Full static analysis of Go source files, Lambda handler, CLI commands, CloudFormation templates, Dockerfile
Action required: Triage each finding below. This PR does not contain fixes — it exists to track and communicate security issues for owner review.

Supersedes: PRs #61 and #69 (both open, now closed). All findings from both previous audits are consolidated here. The /ok-to-test comment on #69 was a CI authorization comment, not a finding dismissal. No findings have been marked as non-issues by repository owners.


HIGH Findings

HIGH-1 — Lambda IAM Role Has Unrestricted Resource Scope for All IAM Operations — Privilege Escalation Path (carry-over from #61, unresolved)

File: internal/cloudformation/templates/lambda-bootstrap.yaml

- Sid: IAMResourceManagement
  Action: [iam:CreateRole, iam:AttachRolePolicy, iam:PutRolePolicy, iam:CreateOpenIDConnectProvider, ...]
  Resource: '*'

Risk: The Lambda execution role can create any IAM role and attach any managed policy (including AdministratorAccess) scoped to ALL resources. There is no permission boundary on created roles. This is a complete privilege escalation path:

  1. Compromised Lambda creates a new IAM role with Resource: *.
  2. Attaches AdministratorAccess.
  3. Assumes the role — achieves full account admin access.

Attack vectors:

  • Compromised container image (see HIGH-5).
  • Forged Lambda event input with malicious cluster name.
  • Lambda event source manipulation (API Gateway, SQS) if not properly authenticated.

Mitigation:

  • Restrict Resource to arn:aws:iam::${AccountId}:role/rosa-* and arn:aws:iam::${AccountId}:instance-profile/rosa-*.
  • Require a permission boundary on all created roles: Condition: { StringEquals: { "iam:PermissionsBoundary": "arn:aws:iam::${AccountId}:policy/rosa-cluster-role-boundary" } }
  • Restrict AttachRolePolicy to ROSA-specific managed policies only.

HIGH-2 — Lambda Role Can Pass Any IAM Role to CloudFormation (carry-over from #61, unresolved)

File: internal/cloudformation/templates/lambda-bootstrap.yaml

- Sid: PassRoleForCloudFormation
  Action: iam:PassRole
  Resource: '*'   # any role in the account
  Condition:
    StringEquals:
      iam:PassedToService: cloudformation.amazonaws.com

Risk: The Lambda can pass any IAM role in the account to CloudFormation stacks it creates. A malicious Lambda invocation could pass an existing admin role to a CloudFormation stack and use it to perform arbitrary AWS operations.

Mitigation: Restrict Resource to arn:aws:iam::${AccountId}:role/rosa-*.


HIGH-3 — Lambda Handler Logs Complete Event Payload Including Sensitive Infrastructure Data (carry-over from #69, unresolved)

File: internal/lambda/handler.go line 38

fmt.Printf("Received event: %+v\n", event)

Risk: Every Lambda invocation logs the complete event to CloudWatch Logs, containing: cluster names, OIDC issuer URLs, OIDC thumbprints, VPC CIDR ranges, subnet CIDRs, and availability zones. An attacker with logs:GetLogEvents on this log group extracts a complete infrastructure topology map from every invocation.

Mitigation: Remove the fmt.Printf line. Log only non-sensitive fields:

slog.Info("received event", "action", event.Action, "cluster_name", event.ClusterName)

HIGH-4 — SHA-1 Used for OIDC Provider Thumbprint Calculation (carry-over from #69, unresolved)

File: internal/crypto/thumbprint.go

import "crypto/sha1"
hash := sha1.Sum(rootCert.Raw)

Risk: SHA-1 is cryptographically broken for collision resistance. While AWS IAM currently requires SHA-1 thumbprints for OIDC providers (a legacy AWS limitation), this creates a dangerous pattern that may be copied elsewhere in the codebase. The dependency becomes critical if AWS weakens OIDC validation.

Mitigation: Add a prominent code comment explicitly stating SHA-1 is used because AWS IAM requires it — not as a design choice. File a tracking issue to migrate when AWS supports SHA-256 OIDC thumbprints. Monitor the AWS changelog.


HIGH-5 — Runtime Dockerfile Uses Unpinned :latest UBI Minimal Image (carry-over from #61, unresolved)

File: Dockerfile lines ~20–22

FROM registry.access.redhat.com/ubi9/ubi-minimal:latest

Risk: Mutable :latest tag. The runtime image is used for the Lambda container that executes with the broad IAM permissions described in HIGH-1. A compromised or regressed UBI9 minimal image introduces vulnerabilities into the Lambda runtime environment.

Compare with aws-nuke-cf/Containerfile in the same organization, which correctly pins to a digest:

FROM registry.access.redhat.com/ubi9/ubi@sha256:cf13fe2aba608ea76abcac5acb3fa4d88821416e7eb45e0623a62c948853ab84

Mitigation: Pin to SHA256 digest.


HIGH-6 — Build Stage Dockerfile Uses Unpinned go-toolset Numeric Tag (NEW)

File: Dockerfile line 2

FROM registry.access.redhat.com/ubi9/go-toolset:1780490457 AS builder

Risk: The numeric tag 1780490457 is a build/version ID that may be mutable (the registry could push a new image with the same tag). The build stage compiles the Lambda binary — a compromised build image produces a backdoored Lambda.

Mitigation: Pin to a SHA256 digest to guarantee reproducibility.


MEDIUM Findings

MED-1 — Lambda IAM Role Has Unrestricted EC2/Route53 Scope — Can Affect Non-ROSA Resources (carry-over from #61, unresolved)

File: internal/cloudformation/templates/lambda-bootstrap.yaml

- Sid: VPCResourceManagement
  Resource: '*'  # ALL VPCs in the account
- Sid: Route53ResourceManagement
  Resource: '*'  # ALL hosted zones in the account

Risk: A compromised Lambda invocation can modify security groups, route tables, and VPC configurations for all VPCs in the account, and create/delete Route53 hosted zones for all domains — disrupting networking and DNS for non-ROSA production workloads.

Mitigation: Restrict EC2 operations to resources tagged ManagedBy: rosactl. Restrict Route53 to ROSA naming patterns.


MED-2 — Cluster Config Output Files Written with World-Readable Permissions 0644 (carry-over from #69, unresolved)

File: internal/commands/cluster/create.go

os.WriteFile(opts.outputFile, jsonBytes, 0644)  // should be 0600

Risk: Cluster configuration JSON (containing IAM role ARNs, VPC IDs, subnet IDs) is world-readable on multi-user hosts. The config file at internal/config/config.go correctly uses 0600 — this is an inconsistency.

Mitigation: Change to 0600.


MED-3 — CLI Config Directory Created with World-Readable Permissions 0755 (carry-over from #61/#69, unresolved)

File: internal/config/config.go

os.MkdirAll(configDirPath, 0755)  // should be 0700

Risk: ~/.rosactl/ is world-readable, revealing the existence of config.json to any user on a shared host.

Mitigation: Change to 0700.


MED-4 — URL Query Parameters Not Properly Encoded in API Calls (carry-over from #69, unresolved)

File: internal/commands/cluster/list.go

Risk: Status filter values are interpolated into query strings using fmt.Sprintf without URL encoding. Special characters in filter values break the query string or inject additional parameters.

Mitigation: Use url.Values.Set() and params.Encode() for all query string construction.


Full findings detail is in SECURITY-AUDIT.md added in this PR.

@openshift-ci

openshift-ci Bot commented Jun 15, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: rosa-regional-platform-ci
Once this PR has been reviewed and has the lgtm label, please assign jmelis for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@rosa-regional-platform-ci, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 57 minutes and 23 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b45b5a55-8027-4cfb-bd79-3a6a8fc10e24

📥 Commits

Reviewing files that changed from the base of the PR and between 80e0a95 and 23173ae.

📒 Files selected for processing (1)
  • SECURITY-AUDIT.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jun 15, 2026
@openshift-ci

openshift-ci Bot commented Jun 15, 2026

Copy link
Copy Markdown

Hi @rosa-regional-platform-ci. Thanks for your PR.

I'm waiting for a openshift-online member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

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

Labels

needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant