diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f7df4..b0bc653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## Changes 12/13/2025 (v2.7.1) + +release(v2.7.1): harden share endpoint headers + suppress deprecated output + +- Replace deprecated FILTER_SANITIZE_STRING token/pass parsing with strict token validation +- Add nosniff + no-cache + restrictive CSP to password prompt response +- Buffer/suppress PHP notices (incl. E_DEPRECATED on PHP 8.4/Termux) in public/api/file/share.php so headers can’t be broken before streaming + +--- + ## Changes 12/13/2025 (v2.7.0) release(v2.7.0): fix critical SVG XSS on public share links diff --git a/public/api/file/share.php b/public/api/file/share.php index 9402b94..5d9d430 100644 --- a/public/api/file/share.php +++ b/public/api/file/share.php @@ -1,34 +1,21 @@ shareFile(); \ No newline at end of file +(new FileController())->shareFile(); \ No newline at end of file diff --git a/scripts/manual-sync.sh b/scripts/manual-sync.sh index bd0cc29..52d8ebb 100644 --- a/scripts/manual-sync.sh +++ b/scripts/manual-sync.sh @@ -2,7 +2,7 @@ # === Update FileRise to v2.3.2 (safe rsync, no composer on demo) === set -Eeuo pipefail -VER="v2.3.2" +VER="v2.7.1" ASSET="FileRise-${VER}.zip" # matches GitHub release asset name WEBROOT="/var/www" @@ -38,16 +38,16 @@ STAGE_DIR="$(find "$TMP" -maxdepth 1 -type d -name 'FileRise*' ! -path "$TMP" | # - DO NOT touch filerise-site / bundles / demo config # - DO NOT touch vendor/ so Stripe + other libs stay intact on demo rsync -a --delete \ - --exclude='public/.htaccess' \ - --exclude='uploads/***' \ - --exclude='users/***' \ - --exclude='metadata/***' \ - --exclude='filerise-bundles/***' \ - --exclude='filerise-config/***' \ - --exclude='filerise-site/***' \ - --exclude='vendor/***' \ - --exclude='.github/***' \ - --exclude='docker-compose.yml' \ + --exclude='/public/.htaccess' \ + --exclude='/uploads/***' \ + --exclude='/users/***' \ + --exclude='/metadata/***' \ + --exclude='/filerise-bundles/***' \ + --exclude='/filerise-config/***' \ + --exclude='/filerise-site/***' \ + --exclude='/vendor/***' \ + --exclude='/.github/***' \ + --exclude='/docker-compose.yml' \ "$STAGE_DIR"/ "$WEBROOT"/ # 4) Ownership (Ubuntu/Debian w/ Apache) diff --git a/src/controllers/FileController.php b/src/controllers/FileController.php index 6a1c5e4..4bc62c1 100644 --- a/src/controllers/FileController.php +++ b/src/controllers/FileController.php @@ -1641,13 +1641,14 @@ class FileController public function shareFile() { - $token = filter_input(INPUT_GET, 'token', FILTER_SANITIZE_STRING); - $providedPass = filter_input(INPUT_GET, 'pass', FILTER_SANITIZE_STRING); + $token = trim((string)($_GET['token'] ?? '')); + $providedPass = (string)($_GET['pass'] ?? ''); - if (empty($token)) { + // adjust if your token format differs + if ($token === '' || !preg_match('/^[a-f0-9]{32}$/i', $token)) { http_response_code(400); header('Content-Type: application/json; charset=utf-8'); - echo json_encode(["error" => "Missing token."]); + echo json_encode(["error" => "Missing or invalid token."]); exit; } @@ -1667,6 +1668,10 @@ class FileController } if (!empty($record['password']) && empty($providedPass)) { + header('X-Content-Type-Options: nosniff'); + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); + header('Pragma: no-cache'); + header("Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'"); header("Content-Type: text/html; charset=utf-8"); ?>