Skip to content

fix: add missing approval gate to check-tflite-files job to prevent untrusted code execution#3500

Open
mohammadmseet-hue wants to merge 1 commit intotensorflow:mainfrom
mohammadmseet-hue:fix/approval-gate-bypass
Open

fix: add missing approval gate to check-tflite-files job to prevent untrusted code execution#3500
mohammadmseet-hue wants to merge 1 commit intotensorflow:mainfrom
mohammadmseet-hue:fix/approval-gate-bypass

Conversation

@mohammadmseet-hue
Copy link
Copy Markdown

Summary

The call-check-tflite-files job in pr_test.yml is missing the needs: [gatekeeper, approval-gate] dependency that every other CI job in this workflow has. This causes it to run unconditionally on pull_request_target synchronize events — including PRs from external forks — bypassing the two-phase approval system.

Security Impact

The called workflow (check_tflite_files.yml) does two things with attacker-controlled input:

  1. Checks out the PR author's commit: ref: ${{ inputs.trigger-sha }}
  2. Executes a shell script from that checkout: tensorflow/lite/micro/tools/ci_build/check_tflite_files.sh

An external attacker who modifies check_tflite_files.sh in their fork achieves arbitrary code execution in the CI runner.

Why permission scoping does NOT mitigate this

In some pull_request_target workflows, permission isolation can limit impact — for example, if the job running untrusted code only has contents: read and a separate job (running only base repo code) holds write tokens. That defense does not apply here, because:

  • The check_tflite_files.yml reusable workflow directly receives TFLM_BOT_TOKEN via the secrets input (line 15-16 of check_tflite_files.yml)
  • It falls back to github.token when the bot token is unavailable: TFLM_BOT_TOKEN: ${{ secrets.tflm-bot-token || github.token }}
  • The attacker's modified script executes in the same job that has access to these tokens
  • No job-level permissions: block restricts the default GITHUB_TOKEN scope

This means the attacker's code runs with write access to the repository.

The Fix

This PR adds the same needs: and if: guards that already protect call-core, call-windows, call-cortex-m, call-xtensa, call-hexagon, and call-riscv:

  call-check-tflite-files:
+   needs: [gatekeeper, approval-gate]
+   if: needs.gatekeeper.outputs.scope != 'none'
    uses: ./.github/workflows/check_tflite_files.yml

Comparison: All jobs in pr_test.yml

Job Has needs: [gatekeeper, approval-gate] Runs attacker code
call-core ✅ Yes Yes (checks out trigger-sha)
call-windows ✅ Yes Yes
call-cortex-m ✅ Yes Yes
call-xtensa ✅ Yes Yes
call-hexagon ✅ Yes Yes
call-riscv ✅ Yes Yes
call-check-tflite-files ❌ No (this PR fixes it) Yes

@google-cla
Copy link
Copy Markdown

google-cla bot commented Mar 22, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@mohammadmseet-hue mohammadmseet-hue force-pushed the fix/approval-gate-bypass branch from 28a9bb4 to d812bdc Compare March 25, 2026 18:25
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