Skip to content

PoC: Demonstrate cache poisoning vulnerability (DO NOT MERGE)#3827

Open
mabrukhany-beep wants to merge 1 commit into
angular:mainfrom
mabrukhany-beep:main
Open

PoC: Demonstrate cache poisoning vulnerability (DO NOT MERGE)#3827
mabrukhany-beep wants to merge 1 commit into
angular:mainfrom
mabrukhany-beep:main

Conversation

@mabrukhany-beep

Copy link
Copy Markdown

This is a security proof-of-concept - DO NOT MERGE

This PR demonstrates a cache poisoning vulnerability in the bazel cache sharing between PR workflows and scheduled workflows.

Vulnerability Details

The pr.yml workflow (triggered by pull_request) and ng-renovate.yml workflow (triggered by schedule) both use the same bazel cache key:
bazel-cache-runner.os− {{ hashFiles('/.bazelversion') }}-hashFiles(

∗∗/WORKSPACE

)− {{ hashFiles('/MODULE.bazel.lock') }}

This means:

  1. A PR workflow can poison the bazel cache
  2. The scheduled ng-renovate.yml workflow restores the poisoned cache
  3. The poisoned cache executes with NG_RENOVATE_USER_ACCESS_TOKEN

PoC Payload

This PR modifies .bazelrc to add environment variables that will be cached by bazel:

  • POC_CACHE_POISONED=true
  • Workspace status command that logs a message

Expected Behavior

When ng-renovate.yml runs on its schedule (every hour at :17 and :47), the bazel cache will contain the poisoned environment variables from this PR workflow.

Impact

An attacker could:

  • Poison the bazel cache with malicious code
  • Exfiltrate NG_RENOVATE_USER_ACCESS_TOKEN when ng-renovate.yml runs
  • Use the token to push code to ALL Angular repos (angular/angular, angular/components, etc.)

Fix Recommendation

  1. Use separate cache keys for PR workflows and scheduled workflows
  2. Or: Disable cache sharing between workflows with different privilege levels
  3. Or: Use actions/cache/restore only (no save) in PR workflows

Note: This PoC is safe and only adds environment variables for demonstration. It does not exfiltrate any secrets.

PoC: Demonstrate cache poisoning vulnerability

This commit modifies .bazelrc to add environment variables that will
be cached by bazel. If the cache is shared with scheduled workflows
(ng-renovate.yml), these variables will be present in those workflows,
proving cache poisoning from PR workflows.

Signed-off-by: mabrukhany-beep <mabrukhany@gmail.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request modifies the .bazelrc file to introduce a Proof of Concept (PoC) demonstrating cache poisoning. The reviewer identified a critical issue where the --workspace_status_command flag is configured with an inline shell command instead of a path to an executable script, which will cause the Bazel build to fail.

Comment thread .bazelrc

build --action_env=POC_CACHE_POISONED=true
test --test_env=POC_CACHE_POISONED=true
build --workspace_status_command="echo 'PoC: Cache poisoned by PR workflow'"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

In Bazel, the --workspace_status_command flag expects a path to an executable binary or script, not an inline shell command with arguments. Specifying "echo 'PoC: Cache poisoned by PR workflow'" directly will cause Bazel to look for an executable with that exact name (including the spaces and quotes) in the PATH or workspace, which will fail and break the build.\n\nTo fix this and make the PoC work as intended, you should create an executable script (e.g., tools/workspace_status.sh) and reference its path:\n\nbash\n#!/bin/bash\necho "PoC: Cache poisoned by PR workflow"\n\n\nAnd update .bazelrc to point to that script.

build --workspace_status_command=tools/workspace_status.sh

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