fix(images): Remi origin over HTTPS first; fail builds older than php.net
Security review of #28: plain-http repo metadata could be replayed to keep a build on old (validly signed) vulnerable PHP. The origin is now tried over HTTPS first, with http only as a fallback (its HTTPS timed out/reset under the 2026-10-21 release load). CI resolves php.net's current release per branch (over HTTPS) and the build fails if the installed PHP is older, so neither a lagging mirror nor replayed metadata can ship a vulnerable PHP. Tested on 192.168.1.193 (almalinux/10-base): rewritten baseurl installs PHP 8.5.12; the gate passes at 8.5.12 and fails at 8.5.99. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e8e3bfd490
commit
af7fd193e5
3 files changed
+56
-4
No files matched your search
@@ -84,6 +84,20 @@ jobs:
|
||||
id: bust
|
||||
run: echo "value=$(date -u +%Y%m%dT%H%M%SZ)-${{ gitea.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# The minimum PHP version this build must ship: php.net's current release for
|
||||
# the branch (over HTTPS). The Dockerfile fails if Remi gave us anything older,
|
||||
# so lagging mirrors or replayed repo metadata can't ship a vulnerable PHP.
|
||||
- name: Resolve current PHP release from php.net
|
||||
id: phpmin
|
||||
run: |
|
||||
set -euo pipefail
|
||||
v="${{ matrix.phpver }}"; branch="${v:0:1}.${v:1}"
|
||||
json=$(curl -fsS --retry 5 --max-time 60 "https://www.php.net/releases/index.php?json&max=1&version=${branch}")
|
||||
min=$(printf '%s' "$json" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(next(iter(d)) if isinstance(d,dict) and d else "")')
|
||||
if [ -z "$min" ]; then echo "::error::no php.net release found for ${branch}"; exit 1; fi
|
||||
echo "php.net current ${branch}: ${min}"
|
||||
echo "min=${min}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Login to Gitea
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
@@ -99,6 +113,7 @@ jobs:
|
||||
build-args: |
|
||||
PHPVER=${{ matrix.phpver }}
|
||||
CACHE_BUST=${{ steps.bust.outputs.value }}
|
||||
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
|
||||
tags: |
|
||||
repo.anhonesthost.net/cloud-hosting-platform/cac:php${{ matrix.phpver }}
|
||||
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac:latest' || '' }}
|
||||
@@ -129,6 +144,20 @@ jobs:
|
||||
id: bust
|
||||
run: echo "value=$(date -u +%Y%m%dT%H%M%SZ)-${{ gitea.run_id }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# The minimum PHP version this build must ship: php.net's current release for
|
||||
# the branch (over HTTPS). The Dockerfile fails if Remi gave us anything older,
|
||||
# so lagging mirrors or replayed repo metadata can't ship a vulnerable PHP.
|
||||
- name: Resolve current PHP release from php.net
|
||||
id: phpmin
|
||||
run: |
|
||||
set -euo pipefail
|
||||
v="${{ matrix.phpver }}"; branch="${v:0:1}.${v:1}"
|
||||
json=$(curl -fsS --retry 5 --max-time 60 "https://www.php.net/releases/index.php?json&max=1&version=${branch}")
|
||||
min=$(printf '%s' "$json" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(next(iter(d)) if isinstance(d,dict) and d else "")')
|
||||
if [ -z "$min" ]; then echo "::error::no php.net release found for ${branch}"; exit 1; fi
|
||||
echo "php.net current ${branch}: ${min}"
|
||||
echo "min=${min}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Login to Gitea
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
@@ -145,6 +174,7 @@ jobs:
|
||||
build-args: |
|
||||
PHPVER=${{ matrix.phpver }}
|
||||
CACHE_BUST=${{ steps.bust.outputs.value }}
|
||||
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
|
||||
tags: |
|
||||
repo.anhonesthost.net/cloud-hosting-platform/cac-fpm:php${{ matrix.phpver }}
|
||||
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-fpm:latest' || '' }}
|
||||
|
||||
Reference in new issue
Block a user