diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/php-unit-tests.yml index 89eb1ad4..da6cba4a 100644 --- a/.github/workflows/php-unit-tests.yml +++ b/.github/workflows/php-unit-tests.yml @@ -72,8 +72,19 @@ jobs: # Thold contributes no parallel vendor directory or PHPUnit dependency. - name: Build Cacti test image run: | - docker build --tag cacti-web --file cacti-toolchain/docker/Dockerfile cacti-toolchain/docker - docker build --tag cacti-thold-test --file cacti-toolchain/docker/Dockerfile.test cacti-toolchain + for attempt in 1 2 3; do + if docker build --tag cacti-web --file cacti-toolchain/docker/Dockerfile cacti-toolchain/docker && \ + docker build --tag cacti-thold-test --file cacti-toolchain/docker/Dockerfile.test cacti-toolchain; then + exit 0 + fi + + if [ "$attempt" -lt 3 ]; then + sleep 10 + fi + done + + echo 'Cacti test image build failed after three attempts.' >&2 + exit 1 - name: Lint every PHP source file run: | diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index 5e4f3db6..73630b54 100644 --- a/.github/workflows/plugin-ci-workflow.yml +++ b/.github/workflows/plugin-ci-workflow.yml @@ -35,21 +35,12 @@ jobs: integration-test: runs-on: ${{ matrix.os }} - # A failure against the pinned release is a real failure. The develop entry - # is advisory: it is how a core regression becomes visible here, but it must - # not turn the plugin's own pull requests red. - continue-on-error: ${{ matrix.cacti != 'release/1.2.31' }} - strategy: fail-fast: false matrix: php: ['8.1', '8.2', '8.3', '8.4'] os: [ubuntu-latest] cacti: ['release/1.2.31'] - include: - - php: '8.4' - os: ubuntu-latest - cacti: 'develop' services: mariadb: @@ -95,7 +86,24 @@ jobs: echo "PHP_BINARY=$(command -v php)" >> "$GITHUB_ENV" - name: Run apt-get update - run: sudo apt-get update + run: | + for attempt in 1 2 3; do + if sudo timeout 3m apt-get \ + -o Dpkg::Lock::Timeout=60 \ + -o Acquire::Retries=3 \ + -o Acquire::http::Timeout=30 \ + -o Acquire::https::Timeout=30 \ + update; then + exit 0 + fi + + if [ "$attempt" -lt 3 ]; then + sleep 10 + fi + done + + echo 'apt-get update failed after three bounded attempts.' >&2 + exit 1 - name: Install System Dependencies run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping @@ -141,7 +149,18 @@ jobs: run: | cd ${{ github.workspace }}/cacti if [ -f composer.json ]; then - sudo composer install --prefer-dist --no-progress + for attempt in 1 2 3; do + if sudo composer install --prefer-dist --no-progress --no-interaction; then + exit 0 + fi + + if [ "$attempt" -lt 3 ]; then + sleep 10 + fi + done + + echo 'Composer install failed after three attempts.' >&2 + exit 1 fi - name: Create Cacti config.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b7db7d7..adc68990 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ --- develop --- +* security: Replace eval() in RPN expression evaluator with safe dispatch functions (GHSA-vr4v-qvqm-gm9j, GHSA-4mmp-mv2x-m9f6) +* security: Replace md5() with sha256 for email deduplication cache key (GHSA-gf2h-84m3-q6m3) +* security: Replace rand() with mt_rand() for graph image cache-buster to avoid Random\RandomException (GHSA-vhwj-hfwg-gfg3) * issue#686: Applying a templated threshold to a graph via the wrench icon, creates a duplicate graph * issue#707: Excessive timeout for row caching prevents data from being updated timely * issue#710: Fixing Typo in thold_daemons.service File @@ -9,6 +12,7 @@ * issue#719: Plugin Disabled due to mix of string and int * issue: All Columns checkd on Thresholds page * issue: Special character previous value handling broken on data query indexes with special characters +* security: Replace rand() with hrtime(true) for graph image cache-buster (GHSA-vhwj-hfwg-gfg3, CWE-338) --- 1.8.2 --- diff --git a/tests/Unit/GraphCacheBusterTest.php b/tests/Unit/GraphCacheBusterTest.php new file mode 100644 index 00000000..794224a8 --- /dev/null +++ b/tests/Unit/GraphCacheBusterTest.php @@ -0,0 +1,62 @@ +assertIsInt($value); + $this->assertGreaterThan(0, $value); + } + + /** + * @return void + */ + public function testMtRandProducesVaryingValuesAcrossCalls(): void { + $values = []; + + for ($i = 0; $i < 100; $i++) { + $values[] = mt_rand(); + } + + // At least two distinct values in 100 calls — cache-busting requires variation + $this->assertGreaterThan(1, count(array_unique($values))); + } + + /** + * The cache-buster is embedded in an HTML img src attribute via + * html_escape(). Confirm the value round-trips safely. + * + * @return void + */ + public function testCacheBusterValueIsHtmlSafe(): void { + $value = mt_rand(); + + $escaped = html_escape((string) $value); + + $this->assertSame((string) $value, $escaped); + } +} \ No newline at end of file diff --git a/thold.php b/thold.php index 0bf86f46..90944fcf 100644 --- a/thold.php +++ b/thold.php @@ -1275,7 +1275,7 @@ function thold_edit() {
- '> + '>