paths:
- vendor/
-# Run tests for php:8.2
-job_lint_app_82:
- image: php:8.2
- before_script: &before_linter_script
+# Aliases and Anchors for reuse
+
+.linter_script: &linter_script
+ - ./vendor/bin/parallel-lint --gitlab --exclude vendor .
+ - ./vendor/bin/php-cs-fixer -vvv check . --using-cache=no --rules=@PSR12,-single_space_around_construct
+.before_script: &before_linter_script
# Install git, the docker php image doesn't have it installed by default
- apt-get update -yqq
- apt-get install git -yqq
- curl -sS https://getcomposer.org/installer | php
# Create composer.json file manually, since this is a project without any non-dev dependencies yet
- php composer.phar require --dev php-parallel-lint/php-parallel-lint
- - php composer.phar require --dev friendsofphp/php-cs-fixer:3.64.0
+ - php composer.phar require --dev friendsofphp/php-cs-fixer:3.93.1
# Install all project dependencies
- php composer.phar install
- script: &linter_script
- - ./vendor/bin/parallel-lint --exclude vendor .
- - ./vendor/bin/php-cs-fixer -vvv check . --using-cache=no --rules=@PSR12,-single_space_around_construct
+
+.enableWarningOnFailure: &linter_warning
+ allow_failure:
+ exit_codes:
+ - 1
+
+
+# Run tests for php:8.5
+job_lint_app_85:
+ image: php:8.5
+ before_script: *before_linter_script
+ script: *linter_script
+
+# Run tests for php:8.4
+job_lint_app_84:
+ image: php:8.4
+ before_script: *before_linter_script
+ script: *linter_script
+
+job_lint_app_83:
+ image: php:8.3
+ before_script: *before_linter_script
+ script: *linter_script
+
+# Run tests for php:8.2
+job_lint_app_82:
+ image: php:8.2
+ before_script: *before_linter_script
+ script: *linter_script
+
+
+# =================
+# Deprecated ones START
+# =================
# Run tests for php:8.1
job_lint_app_81:
image: php:8.1
before_script: *before_linter_script
script: *linter_script
+ <<: *linter_warning
+
+
# Run tests for php:7.4
job_lint_app_74:
image: php:7.4
before_script: *before_linter_script
script: *linter_script
+ <<: *linter_warning
+
+# =================
+# Deprecated ones END
+# =================
publish:
image: docker:latest
5. Follow the installation wizard, it should propose you the same data folder or even update automatically
6. Check your `/lib/config.local.php` and compare it with the `/lib/config.original.php` to see if new configuration items are available. If a new item is missing in your `config.local.php`, this may trigger some errors as Jirafeau may expect to have them.
+## Version 4.7.x (not yet released)
+
+- Favicon was missing in the `modern` theme
+- ...
+
## Version 4.7.1
-- Fixed another possibility to bypass the checks for [CVE-2022-30110](https://www.cve.org/CVERecord?id=CVE-2022-30110), [CVE-2024-12326](https://www.cve.org/CVERecord?id=CVE-2024-12326) and [CVE-2025-7066](https://www.cve.org/CVERecord?id=CVE-2025-7066) (prevent preview of SVG images and other critical files) by sending a manipulated HTTP request with a MIME type like "image". When doing the preview, the browser tries to automatically detect the MIME type resulting in detecting SVG and possibly executing JavaScript code. To prevent this, MIME sniffing is disabled.
+- Fixed another possibility to bypass the checks for [CVE-2022-30110](https://www.cve.org/CVERecord?id=CVE-2022-30110), [CVE-2024-12326](https://www.cve.org/CVERecord?id=CVE-2024-12326) and [CVE-2025-7066](https://www.cve.org/CVERecord?id=CVE-2025-7066) (prevent preview of SVG images and other critical files) by sending a manipulated HTTP request with a MIME type like "image". When doing the preview, the browser tries to automatically detect the MIME type resulting in detecting SVG and possibly executing JavaScript code. To prevent this, MIME sniffing is disabled. This issue has subsequently been reported as [CVE-2026-1466](https://www.cve.org/CVERecord?id=CVE-2026-1466).
- The default value of `max_upload_chunk_size_bytes` was set to `5000000`. Higher values could trigger a bug Chromium-based browsers on servers with HTTP/3 enabled, causing asynchronous uploads to fail.
- Docker image: Updated PHP to 8.3 and removed `mime-types.conf` from `lighttpd.conf`
- Upgrade from 4.7.0: in-place upgrade, you also should set `max_upload_chunk_size_bytes` to `5000000` in your `config.local.php`!
require(JIRAFEAU_ROOT.'lib/template/footer.php');
exit;
} else {
- if (hash_equals($link['key'], md5($_POST['key']))) {
+ if (strpos($link['key'], '[SHA256]') == 0 && hash_equals(substr($link['key'], 8), hash('sha256', $_POST['key']))) {
+ $password_challenged = true;
+ } elseif (hash_equals($link['key'], md5($_POST['key']))) {
$password_challenged = true;
} else {
sleep(2);
*/
$cfg['debug'] = false;
+/* Enable this debug flag to enforce the classic (synchronous) file upload mechanism.
+ */
+$cfg['debug_enforce_classic_upload'] = false;
+
/* Set Jirafeau's maximal upload chunk
* When Jirafeau upload a large file, Jirafeau sends several data chunks to fit server's capabilities.
* Jirafeau tries to upload each data chunk with the maximal size allowed by PHP (post_max_size and upload_max_filesize).
req.upload.addEventListener ("progress", upload_progress, false);
req.addEventListener ("error", XHRErrorHandler, false);
req.addEventListener ("abort", XHRErrorHandler, false);
- req.onreadystatechange = function ()
+ req.onload = function ()
{
- if (req.readyState == 4 && req.status == 200)
+ if (req.status === 200)
{
var res = req.responseText;
function check_html5_file_api ()
{
+<?php
+ if (isset($cfg['debug_enforce_classic_upload']) && $cfg['debug_enforce_classic_upload']) { ?>
+ // Enforce classic upload is enabled through config!
+ return false;
+<?php
+ }
+?>
return window.File && window.FileReader && window.FileList && window.Blob;
}
error_log("PHP extension sodium not loaded, won't encrypt in Jirafeau");
}
if ($crypt_module_enabled == true && extension_loaded('sodium') == true) {
- $crypt_key = jirafeau_encrypt_file($file_path, $file_path.'crypt');
+ $crypt_key = jirafeau_encrypt_file($file_path, $file_path.'.crypt');
if (strlen($crypt_key) > 0) {
- if (rename($file_path.'crypt', $file_path) === true) {
+ if (rename($file_path.'.crypt', $file_path) === true) {
$crypted = true;
}
}
/* hash password or empty. */
$password = '';
if (!empty($key)) {
- $password = md5($key);
+ $password = '[SHA256]' . hash('sha256', $key);
}
/* create link file */
$handle,
$name . NL. $mime_type . NL. $size . NL. $password . NL. $time .
NL . $hash. NL . ($one_time_download ? 'O' : 'R') . NL . time() .
- NL . $ip . NL. $delete_link_code . NL . ($crypted ? 'C' : 'O')
+ NL . $ip . NL. $delete_link_code . NL . ($crypted ? 'C2' : 'O')
);
fclose($handle);
$hash_link = substr(base_16_to_64(md5_file($link_tmp_name)), 0, $link_name_length);
$w_path = $p . $ref . '_data';
touch($w_path);
- /* md5 password or empty */
+ /* sha256 password or empty */
$password = '';
if (!empty($key)) {
- $password = md5($key);
+ $password = '[SHA256]' . hash('sha256', $key);
}
/* Store information. */
function jirafeau_admin_session_start()
{
$_SESSION['admin_auth'] = true;
- $_SESSION['admin_csrf'] = md5(uniqid(mt_rand(), true));
+ $_SESSION['admin_csrf'] = hash('sha256', uniqid(mt_rand(), true));
}
function jirafeau_session_end()
/* Jirafeau package */
define('JIRAFEAU_PACKAGE', 'Jirafeau');
-define('JIRAFEAU_VERSION', '4.7.1');
+define('JIRAFEAU_VERSION', '4.7.x-dev');
define('JIRAFEAU_WEBSITE', 'https://gitlab.com/jirafeau/Jirafeau');
echo 'Error 9';
exit;
}
- if (strlen($link['key']) > 0 && md5($key) != $link['key']) {
+ if (strlen($link['key']) > 0 && hash('sha256', $key) != $link['key']) {
sleep(2);
echo 'Error 10';
exit;