prettier-run for code-formatting
This commit is contained in:
@@ -95,7 +95,8 @@ final class ImageFetch
|
|||||||
foreach ($cfg['whitelist_hosts'] as $allowed) {
|
foreach ($cfg['whitelist_hosts'] as $allowed) {
|
||||||
$allowed = strtolower($allowed);
|
$allowed = strtolower($allowed);
|
||||||
if ($host === $allowed || str_ends_with($host, '.' . $allowed)) {
|
if ($host === $allowed || str_ends_with($host, '.' . $allowed)) {
|
||||||
$ok = true; break;
|
$ok = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$ok) {
|
if (!$ok) {
|
||||||
@@ -270,15 +271,18 @@ final class ImageFetch
|
|||||||
{
|
{
|
||||||
$stripped = strtok($url, '?#');
|
$stripped = strtok($url, '?#');
|
||||||
$ext = strtolower(pathinfo((string) $stripped, PATHINFO_EXTENSION));
|
$ext = strtolower(pathinfo((string) $stripped, PATHINFO_EXTENSION));
|
||||||
if (!preg_match('/^[a-z0-9]{1,5}$/i', $ext)) $ext = 'jpg';
|
if (!preg_match('/^[a-z0-9]{1,5}$/i', $ext))
|
||||||
|
$ext = 'jpg';
|
||||||
return bin2hex(random_bytes(10)) . '.' . $ext;
|
return bin2hex(random_bytes(10)) . '.' . $ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function isValidHttpUrl(string $url): bool
|
private static function isValidHttpUrl(string $url): bool
|
||||||
{
|
{
|
||||||
if (!filter_var($url, FILTER_VALIDATE_URL)) return false;
|
if (!filter_var($url, FILTER_VALIDATE_URL))
|
||||||
|
return false;
|
||||||
$p = parse_url($url);
|
$p = parse_url($url);
|
||||||
if (!$p || empty($p['scheme']) || empty($p['host'])) return false;
|
if (!$p || empty($p['scheme']) || empty($p['host']))
|
||||||
|
return false;
|
||||||
$s = strtolower($p['scheme']);
|
$s = strtolower($p['scheme']);
|
||||||
return $s === 'http' || $s === 'https';
|
return $s === 'http' || $s === 'https';
|
||||||
}
|
}
|
||||||
@@ -286,11 +290,13 @@ final class ImageFetch
|
|||||||
private static function originFromUrl(string $url): string
|
private static function originFromUrl(string $url): string
|
||||||
{
|
{
|
||||||
$p = parse_url($url);
|
$p = parse_url($url);
|
||||||
if (!$p || empty($p['scheme']) || empty($p['host'])) return '';
|
if (!$p || empty($p['scheme']) || empty($p['host']))
|
||||||
|
return '';
|
||||||
$port = '';
|
$port = '';
|
||||||
if (!empty($p['port'])) {
|
if (!empty($p['port'])) {
|
||||||
$default = ($p['scheme'] === 'https') ? 443 : 80;
|
$default = ($p['scheme'] === 'https') ? 443 : 80;
|
||||||
if ((int)$p['port'] !== $default) $port = ':'.$p['port'];
|
if ((int) $p['port'] !== $default)
|
||||||
|
$port = ':' . $p['port'];
|
||||||
}
|
}
|
||||||
return $p['scheme'] . '://' . $p['host'] . $port . '/';
|
return $p['scheme'] . '://' . $p['host'] . $port . '/';
|
||||||
}
|
}
|
||||||
@@ -298,11 +304,14 @@ final class ImageFetch
|
|||||||
private static function hostResolvesPublic(string $host): bool
|
private static function hostResolvesPublic(string $host): bool
|
||||||
{
|
{
|
||||||
$recs = @dns_get_record($host, DNS_A + DNS_AAAA);
|
$recs = @dns_get_record($host, DNS_A + DNS_AAAA);
|
||||||
if (!$recs || !count($recs)) return false;
|
if (!$recs || !count($recs))
|
||||||
|
return false;
|
||||||
foreach ($recs as $r) {
|
foreach ($recs as $r) {
|
||||||
$ip = $r['type'] === 'A' ? ($r['ip'] ?? null) : ($r['ipv6'] ?? null);
|
$ip = $r['type'] === 'A' ? ($r['ip'] ?? null) : ($r['ipv6'] ?? null);
|
||||||
if (!$ip) continue;
|
if (!$ip)
|
||||||
if (self::isPrivateIp($ip)) return false;
|
continue;
|
||||||
|
if (self::isPrivateIp($ip))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -316,7 +325,9 @@ final class ImageFetch
|
|||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
foreach ($cidrs as $c) if (self::ipInCidr($ip, $c)) return true;
|
foreach ($cidrs as $c)
|
||||||
|
if (self::ipInCidr($ip, $c))
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,10 +338,12 @@ final class ImageFetch
|
|||||||
$mask = (int) $mask;
|
$mask = (int) $mask;
|
||||||
$binIp = inet_pton($ip);
|
$binIp = inet_pton($ip);
|
||||||
$binSubnet = inet_pton($subnet);
|
$binSubnet = inet_pton($subnet);
|
||||||
if ($binIp === false || $binSubnet === false) return false;
|
if ($binIp === false || $binSubnet === false)
|
||||||
|
return false;
|
||||||
$bytes = intdiv($mask, 8);
|
$bytes = intdiv($mask, 8);
|
||||||
$bits = $mask % 8;
|
$bits = $mask % 8;
|
||||||
if ($bytes && substr($binIp, 0, $bytes) !== substr($binSubnet, 0, $bytes)) return false;
|
if ($bytes && substr($binIp, 0, $bytes) !== substr($binSubnet, 0, $bytes))
|
||||||
|
return false;
|
||||||
if ($bits) {
|
if ($bits) {
|
||||||
$b1 = ord($binIp[$bytes]) & (0xFF << (8 - $bits));
|
$b1 = ord($binIp[$bytes]) & (0xFF << (8 - $bits));
|
||||||
$b2 = ord($binSubnet[$bytes]) & (0xFF << (8 - $bits));
|
$b2 = ord($binSubnet[$bytes]) & (0xFF << (8 - $bits));
|
||||||
@@ -342,7 +355,8 @@ final class ImageFetch
|
|||||||
$mask = (int) $mask;
|
$mask = (int) $mask;
|
||||||
$ipL = ip2long($ip);
|
$ipL = ip2long($ip);
|
||||||
$subL = ip2long($subnet);
|
$subL = ip2long($subnet);
|
||||||
if ($ipL === false || $subL === false) return false;
|
if ($ipL === false || $subL === false)
|
||||||
|
return false;
|
||||||
$maskL = -1 << (32 - $mask);
|
$maskL = -1 << (32 - $mask);
|
||||||
return (($ipL & $maskL) === ($subL & $maskL));
|
return (($ipL & $maskL) === ($subL & $maskL));
|
||||||
}
|
}
|
||||||
@@ -350,7 +364,8 @@ final class ImageFetch
|
|||||||
|
|
||||||
private static function fail(?string $tmp, ?string $cerr, int $http, string $msg): array
|
private static function fail(?string $tmp, ?string $cerr, int $http, string $msg): array
|
||||||
{
|
{
|
||||||
if ($tmp && is_file($tmp)) @unlink($tmp);
|
if ($tmp && is_file($tmp))
|
||||||
|
@unlink($tmp);
|
||||||
return [
|
return [
|
||||||
'ok' => false,
|
'ok' => false,
|
||||||
'tmp_path' => null,
|
'tmp_path' => null,
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ declare(strict_types=1);
|
|||||||
/* ========= Session & Bootstrap ========= */
|
/* ========= Session & Bootstrap ========= */
|
||||||
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
|
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
|
||||||
session_set_cookie_params([
|
session_set_cookie_params([
|
||||||
'lifetime'=>0,'path'=>'/','secure'=>$secure,'httponly'=>true,'samesite'=>'Lax',
|
'lifetime' => 0,
|
||||||
|
'path' => '/',
|
||||||
|
'secure' => $secure,
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Lax',
|
||||||
]);
|
]);
|
||||||
session_name('WLISTSESSID');
|
session_name('WLISTSESSID');
|
||||||
session_start();
|
session_start();
|
||||||
@@ -14,37 +18,55 @@ require_once __DIR__ . '/config/config.php';
|
|||||||
|
|
||||||
/* ===== Debug Toggle (wie item.php) ===== */
|
/* ===== Debug Toggle (wie item.php) ===== */
|
||||||
if (!empty($app_debug)) {
|
if (!empty($app_debug)) {
|
||||||
ini_set('display_errors','1'); ini_set('display_startup_errors','1'); ini_set('log_errors','1');
|
ini_set('display_errors', '1');
|
||||||
if (!is_dir(__DIR__.'/logs')) { @mkdir(__DIR__.'/logs',0750,true); }
|
ini_set('display_startup_errors', '1');
|
||||||
ini_set('error_log', __DIR__.'/logs/php-error.log'); error_reporting(E_ALL);
|
ini_set('log_errors', '1');
|
||||||
|
if (!is_dir(__DIR__ . '/logs')) {
|
||||||
|
@mkdir(__DIR__ . '/logs', 0750, true);
|
||||||
|
}
|
||||||
|
ini_set('error_log', __DIR__ . '/logs/php-error.log');
|
||||||
|
error_reporting(E_ALL);
|
||||||
} else {
|
} else {
|
||||||
ini_set('display_errors','0'); ini_set('display_startup_errors','0'); ini_set('log_errors','1');
|
ini_set('display_errors', '0');
|
||||||
if (!is_dir(__DIR__.'/logs')) { @mkdir(__DIR__.'/logs',0750,true); }
|
ini_set('display_startup_errors', '0');
|
||||||
ini_set('error_log', __DIR__.'/logs/php-error.log'); error_reporting(E_ALL);
|
ini_set('log_errors', '1');
|
||||||
|
if (!is_dir(__DIR__ . '/logs')) {
|
||||||
|
@mkdir(__DIR__ . '/logs', 0750, true);
|
||||||
|
}
|
||||||
|
ini_set('error_log', __DIR__ . '/logs/php-error.log');
|
||||||
|
error_reporting(E_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============= Helpers ============= */
|
/* ============= Helpers ============= */
|
||||||
function fail(string $msg, int $code=400): void {
|
function fail(string $msg, int $code = 400): void
|
||||||
|
{
|
||||||
http_response_code($code);
|
http_response_code($code);
|
||||||
// kleine Flash-Message für index.php
|
// kleine Flash-Message für index.php
|
||||||
$_SESSION['flash'] = ['msg' => $msg, 'type' => ($code >= 400 ? 'danger' : 'success')];
|
$_SESSION['flash'] = ['msg' => $msg, 'type' => ($code >= 400 ? 'danger' : 'success')];
|
||||||
safe_redirect_back();
|
safe_redirect_back();
|
||||||
}
|
}
|
||||||
function db(): mysqli {
|
function db(): mysqli
|
||||||
|
{
|
||||||
global $servername, $username, $password, $db;
|
global $servername, $username, $password, $db;
|
||||||
$conn = new mysqli($servername, $username, $password, $db);
|
$conn = new mysqli($servername, $username, $password, $db);
|
||||||
if ($conn->connect_error) fail('Interner Fehler (DB)', 500);
|
if ($conn->connect_error)
|
||||||
|
fail('Interner Fehler (DB)', 500);
|
||||||
$conn->set_charset('utf8mb4');
|
$conn->set_charset('utf8mb4');
|
||||||
return $conn;
|
return $conn;
|
||||||
}
|
}
|
||||||
function require_csrf(): void {
|
function require_csrf(): void
|
||||||
|
{
|
||||||
$t = (string) ($_POST['csrf'] ?? '');
|
$t = (string) ($_POST['csrf'] ?? '');
|
||||||
if (empty($_SESSION['csrf']) || !hash_equals($_SESSION['csrf'], $t)) {
|
if (empty($_SESSION['csrf']) || !hash_equals($_SESSION['csrf'], $t)) {
|
||||||
fail('Ungültiges CSRF-Token', 403);
|
fail('Ungültiges CSRF-Token', 403);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function e(string $s): string { return htmlspecialchars($s, ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8'); }
|
function e(string $s): string
|
||||||
function safe_redirect_back(): void {
|
{
|
||||||
|
return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||||
|
}
|
||||||
|
function safe_redirect_back(): void
|
||||||
|
{
|
||||||
$ref = (string) ($_SERVER['HTTP_REFERER'] ?? '');
|
$ref = (string) ($_SERVER['HTTP_REFERER'] ?? '');
|
||||||
if ($ref === '' || stripos($ref, 'http') !== 0) {
|
if ($ref === '' || stripos($ref, 'http') !== 0) {
|
||||||
$host = $_SERVER['HTTP_HOST'] ?? '';
|
$host = $_SERVER['HTTP_HOST'] ?? '';
|
||||||
@@ -67,8 +89,10 @@ $wishId = (int)($_POST['wishid'] ?? -1);
|
|||||||
$pw = (string) ($_POST['WishPassword'] ?? '');
|
$pw = (string) ($_POST['WishPassword'] ?? '');
|
||||||
$reservedstat = (int) ($_POST['reservedstat'] ?? 0); // 0 = setzen, 1 = aufheben
|
$reservedstat = (int) ($_POST['reservedstat'] ?? 0); // 0 = setzen, 1 = aufheben
|
||||||
|
|
||||||
if ($wishId <= 0) fail('Ungültige Wunsch-ID', 400);
|
if ($wishId <= 0)
|
||||||
if ($pw === '') fail('Passwort erforderlich', 400);
|
fail('Ungültige Wunsch-ID', 400);
|
||||||
|
if ($pw === '')
|
||||||
|
fail('Passwort erforderlich', 400);
|
||||||
|
|
||||||
$conn = db();
|
$conn = db();
|
||||||
|
|
||||||
@@ -79,7 +103,9 @@ $stmt->bind_param('i', $wishId);
|
|||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$res = $stmt->get_result();
|
$res = $stmt->get_result();
|
||||||
if (!$res || !($row = $res->fetch_assoc())) {
|
if (!$res || !($row = $res->fetch_assoc())) {
|
||||||
$stmt->close(); $conn->close(); fail('Wunsch nicht gefunden', 404);
|
$stmt->close();
|
||||||
|
$conn->close();
|
||||||
|
fail('Wunsch nicht gefunden', 404);
|
||||||
}
|
}
|
||||||
$qty = max(1, (int) $row['qty']);
|
$qty = max(1, (int) $row['qty']);
|
||||||
$stmt->close();
|
$stmt->close();
|
||||||
@@ -90,7 +116,8 @@ $stmt = $conn->prepare('SELECT COUNT(*) AS c FROM wishes_reservations WHERE wish
|
|||||||
$stmt->bind_param('i', $wishId);
|
$stmt->bind_param('i', $wishId);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$res = $stmt->get_result();
|
$res = $stmt->get_result();
|
||||||
if ($res && ($row = $res->fetch_assoc())) $cnt = (int)$row['c'];
|
if ($res && ($row = $res->fetch_assoc()))
|
||||||
|
$cnt = (int) $row['c'];
|
||||||
$stmt->close();
|
$stmt->close();
|
||||||
|
|
||||||
/* --- Operationen --- */
|
/* --- Operationen --- */
|
||||||
@@ -104,7 +131,8 @@ if ($reservedstat === 0) {
|
|||||||
$ins = $conn->prepare('INSERT INTO wishes_reservations (wish_id, pass_hash, created_at) VALUES (?, ?, NOW())');
|
$ins = $conn->prepare('INSERT INTO wishes_reservations (wish_id, pass_hash, created_at) VALUES (?, ?, NOW())');
|
||||||
$ins->bind_param('is', $wishId, $hash);
|
$ins->bind_param('is', $wishId, $hash);
|
||||||
if (!$ins->execute()) {
|
if (!$ins->execute()) {
|
||||||
$ins->close(); $conn->close();
|
$ins->close();
|
||||||
|
$conn->close();
|
||||||
fail('Reservierung fehlgeschlagen', 500);
|
fail('Reservierung fehlgeschlagen', 500);
|
||||||
}
|
}
|
||||||
$ins->close();
|
$ins->close();
|
||||||
|
|||||||
Reference in New Issue
Block a user