turnstile

Drupal paywall plugin
Log | Files | Refs | README | LICENSE

commit 8d3c6d195052b7cc24d4b5688b72ed6b6b944ff7
parent 2e4e10f0e19b8140f48a0a79c91419a2204d188c
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 20 May 2026 22:39:26 +0200

improve input validation for data from merchant backend

Diffstat:
Msrc/TalerMerchantApiService.php | 48+++++++++++++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/src/TalerMerchantApiService.php b/src/TalerMerchantApiService.php @@ -436,24 +436,42 @@ class TalerMerchantApiService { $result = $base; $now = time(); foreach ($r->data['token_families'] as $family) { - $valid_before = ($family['valid_before']['t_s'] === 'never') + // Defensively skip malformed entries rather than dereferencing + // missing keys (which would emit PHP warnings and could yield + // bogus comparisons). + $slug = $family['slug'] ?? NULL; + if (!is_string($slug) || $slug === '') { + $this->logger->warning('Token family entry without a usable slug, skipping it.'); + continue; + } + if (($family['kind'] ?? NULL) !== 'subscription') { + $this->logger->info('Token family @slug is not a subscription, skipping it.', ['@slug' => $slug]); + continue; + } + $valid_after_raw = $family['valid_after']['t_s'] ?? NULL; + $valid_before_raw = $family['valid_before']['t_s'] ?? NULL; + if (!is_int($valid_after_raw) || $valid_before_raw === NULL) { + $this->logger->warning('Token family @slug has malformed validity window, skipping it.', ['@slug' => $slug]); + continue; + } + $valid_before = ($valid_before_raw === 'never') ? PHP_INT_MAX - : $family['valid_before']['t_s']; - if (($family['kind'] === 'subscription') && - ($family['valid_after']['t_s'] < $now) && - ($valid_before >= $now)) { - $slug = $family['slug']; - $result[$slug] = [ - 'name' => $family['name'], - 'label' => $slug, - 'valid_before_s' => $valid_before, - 'description' => $family['description'], - 'description_i18n' => ($family['description_i18n'] ?? NULL), - ]; + : (is_int($valid_before_raw) ? $valid_before_raw : NULL); + if ($valid_before === NULL) { + $this->logger->warning('Token family @slug has non-integer valid_before, skipping it.', ['@slug' => $slug]); + continue; } - else { - $this->logger->info('Token family @slug is not valid right now, skipping it.', ['@slug' => $family['slug']]); + if (!($valid_after_raw < $now && $valid_before >= $now)) { + $this->logger->info('Token family @slug is not valid right now, skipping it.', ['@slug' => $slug]); + continue; } + $result[$slug] = [ + 'name' => $family['name'] ?? $slug, + 'label' => $slug, + 'valid_before_s' => $valid_before, + 'description' => $family['description'] ?? '', + 'description_i18n' => $family['description_i18n'] ?? NULL, + ]; } \Drupal::cache()->set($cid, $result, time() + self::CACHE_BACKEND_DATA_SECONDS); return new TalerBackendResult(TalerBackendErrorKind::OK, httpStatus: $r->httpStatus, data: $result);