fix: harden PHP type handling across all endpoints

This commit is contained in:
Alexander Schmidt
2026-03-26 07:57:11 +01:00
parent 5d38946c53
commit 2263fbf659
7 changed files with 97 additions and 37 deletions

18
s.php
View File

@@ -1,5 +1,7 @@
<?php
$code = trim($_SERVER['PATH_INFO'] ?? $_GET['c'] ?? '', '/');
$pathInfo = isset($_SERVER['PATH_INFO']) && is_string($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : null;
$queryCode = isset($_GET['c']) && is_string($_GET['c']) ? $_GET['c'] : '';
$code = trim($pathInfo ?? $queryCode, '/');
if (empty($code) || !preg_match('/^[a-z0-9]{4,10}$/', $code)) {
http_response_code(404);
@@ -14,7 +16,9 @@ if (!file_exists($dbFile)) {
exit;
}
$urls = json_decode(file_get_contents($dbFile), true) ?: [];
$rawUrls = file_get_contents($dbFile);
$decodedUrls = is_string($rawUrls) ? json_decode($rawUrls, true) : [];
$urls = is_array($decodedUrls) ? $decodedUrls : [];
if (!isset($urls[$code])) {
http_response_code(404);
@@ -24,11 +28,12 @@ if (!isset($urls[$code])) {
// Support both old format (string) and new format (array with hash & signature)
$data = $urls[$code];
$hash = is_array($data) ? $data['h'] : $data;
$signature = is_array($data) ? $data['s'] : null;
$hash = is_array($data) ? ($data['h'] ?? '') : $data;
$hash = is_string($hash) ? $hash : '';
$signature = is_array($data) ? ($data['s'] ?? null) : null;
// Verify HMAC signature if present (detect server-side tampering)
if ($signature) {
if (is_string($signature) && $signature !== '') {
require_once __DIR__ . '/api/_helpers.php';
$expected_sig = hash_hmac('sha256', $hash, get_hmac_secret());
if (!hash_equals($expected_sig, $signature)) {
@@ -37,6 +42,7 @@ if ($signature) {
}
}
$base = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
$host = isset($_SERVER['HTTP_HOST']) && is_string($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'xmrpay.link';
$base = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $host;
header('Location: ' . $base . '/#' . $hash . '&c=' . $code, true, 302);
exit;