Skip to content

RHOAIENG-64892: CVE-2026-48710 rhoai/odh-pipeline-runtime-pytorch-cuda-py312-rhel9: Starlette: Security restriction bypass via malformed HTTP Host header [rhoai-3.3] #5117

RHOAIENG-64892: CVE-2026-48710 rhoai/odh-pipeline-runtime-pytorch-cuda-py312-rhel9: Starlette: Security restriction bypass via malformed HTTP Host header [rhoai-3.3]

RHOAIENG-64892: CVE-2026-48710 rhoai/odh-pipeline-runtime-pytorch-cuda-py312-rhel9: Starlette: Security restriction bypass via malformed HTTP Host header [rhoai-3.3] #5117

---
"name": "Build Notebooks (pr, RHEL images)"
"on":
"pull_request_target":
"paths-ignore":
# Don't build images if the only thing that changed is image digests in manifests
- manifests/base/params-latest.env
- manifests/base/params.env
# In fact, skip the build if there are only changes in manifests and nowhere else
- manifests/**
# BEWARE: This GitHub Actions workflow runs on pull_request_target, meaning it has access to our secrets
# see https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-secrets
# and https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
permissions:
contents: read
packages: read
concurrency:
group: ${{ format('build-notebooks-pr-rhel-{0}', github.event.pull_request.number) }}
cancel-in-progress: true
jobs:
# RHAIENG-3914: standard permission gate recognized by security scanners
authorize:
name: Authorize
permissions: {} # only needs implicit metadata:read for getCollaboratorPermissionLevel
runs-on: ubuntu-latest
outputs:
authorized: ${{ steps.check.outputs.authorized }}
steps:
- name: Check collaborator permission
id: check
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
# language=javascript
script: |
// Same-repo PRs are handled by build-notebooks-pr.yaml (build-rhoai job)
// which uses pull_request trigger — no need for pull_request_target here.
const headRepo = context.payload.pull_request.head.repo.full_name;
const baseRepo = context.payload.pull_request.base.repo.full_name;
if (headRepo === baseRepo) {
core.info(`Same-repo PR (${headRepo}) — skipping, handled by build-notebooks-pr.yaml`);
core.setOutput('authorized', 'false');
return;
}
// Fork PRs require the PR author to have write/admin/maintain permission.
// NOTE: use pull_request.user.login, NOT context.actor — context.actor is
// whoever triggered the event (e.g. a maintainer reopening the PR), not the
// PR author. Checking context.actor would bypass the gate if a maintainer
// interacts with a fork PR.
const prAuthor = context.payload.pull_request.user.login;
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: prAuthor,
});
const allowed = ['write', 'admin', 'maintain'].includes(data.permission);
core.setOutput('authorized', String(allowed));
if (!allowed) {
core.warning(`Fork PR author ${prAuthor} has '${data.permission}' permission, requires write/admin/maintain`);
}
gen:
name: Generate job matrix
needs: [authorize]
if: needs.authorize.outputs.authorized == 'true'
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.gen.outputs.matrix }}
has_jobs: ${{ steps.gen.outputs.has_jobs }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
if: ${{ github.event_name == 'pull_request_target' }}
with:
ref: "refs/pull/${{ github.event.number }}/merge"
persist-credentials: false # https://github.com/actions/checkout/issues/2312
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
if: ${{ github.event_name != 'pull_request_target' }}
with:
persist-credentials: false # https://github.com/actions/checkout/issues/2312
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "stable"
cache-dependency-path: "scripts/buildinputs/go.mod"
# RHAIENG-3914: use env vars to prevent GitHub Actions expression injection
- name: Determine targets to build based on changed files
if: ${{ github.event_name == 'pull_request_target' }}
run: |
set -x
git fetch --no-tags origin "pull/${PR_NUMBER}/head:${HEAD_REF}"
git fetch --no-tags origin "+refs/heads/${BASE_REF}:refs/remotes/origin/${BASE_REF}"
python3 ci/cached-builds/gen_gha_matrix_jobs.py \
--from-ref "origin/${BASE_REF}" \
--to-ref "${HEAD_REF}" \
--rhel-images include-only
id: gen
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
shell: bash
build:
name: "${{ matrix.target }} · ${{ matrix.platform }}"
needs: ["authorize", "gen"]
strategy:
fail-fast: false
matrix: "${{ fromJson(needs.gen.outputs.matrix) }}"
uses: ./.github/workflows/build-notebooks-TEMPLATE.yaml
if: ${{ fromJson(needs.gen.outputs.has_jobs) }}
with:
target: "${{ matrix.target }}"
python: "${{ matrix.python }}"
github: "${{ toJSON(github) }}"
platform: "${{ matrix.platform }}"
subscription: "${{ matrix.subscription }}"
secrets: inherit