github zelon88/HRConvert2 v4.0.0
HRConvert2 v4.0.0

4 hours ago

This release covers everything since v3.8.6: fourteen versions of work, v3.8.7 through v4.0.0. It finishes the move to a portable, sandboxed conversion Engine. It also fixes two reported vulnerabilities and several more found in review, and it is the first release with every pipeline's dependencies formally audited.

The full itemized record is in [Documentation/CHANGELOG.txt](https://github.com/zelon88/HRConvert2/blob/master/Documentation/CHANGELOG.txt).


🏆 Security Advisories & Credit

Both advisories fixed in this release were reported by Takaya Sato ([@dagadjno](https://github.com/dagadjno)). Thank you for two careful, detailed reports, and for the proofs of concept the fixes were built and tested against.

[GHSA-mqvr-h4q5-chg9](GHSA-mqvr-h4q5-chg9): OpenSCAD sanitizer bypass (fixed in v3.9.8)

The sanitizer found every file reading call in an uploaded OpenSCAD source, but the rewrite that removed them worked on whole lines, commenting out the line a call started on. A block comment closing part way along that line swallowed the marker, and the call after it stayed live. dagadjno also noted that the test tool only ever exercised the finder, which is why nothing caught it.

  • Calls are now removed by their exact character positions and replaced with whitespace of the same length. A comment marker is never written.
  • The rewritten source is scanned again before it renders. Anything still visible refuses the file with new error 27009.
  • The test tool now tests the rewrite as well as the finder. Its new cases reproduced the bypass against the old code before the fix went in.
  • [ABOUT_SCAD_SANITIZATION.txt](https://github.com/zelon88/HRConvert2/blob/master/Documentation/ABOUT_SCAD_SANITIZATION.txt) records the subsystem, its history and what each advisory taught.

[GHSA-mqqw-cx3x-cf7w](GHSA-mqqw-cx3x-cf7w): Links in uploaded archives (fixed in v3.9.7)

A link restored from an uploaded archive was neither a file nor a directory, so cleanup skipped it, its folder could not be removed, and every later request failed. A link pointing outside the extraction folder could also copy a file such as /etc/passwd into the archive the user downloaded.

  • Cleanup removes links, FIFOs, sockets and device nodes by their own path and never follows a link.
  • Extraction keeps only links that resolve to a file inside the staging folder. Everything else is removed before it reaches cleanup.
  • One object that can't be removed no longer takes the whole instance offline.

🔐 Other Security Fixes

These were found in review, not reported:

  • Virus scanning gave false verdicts. A bug in how the sandbox's result was read meant the ClamAV pipeline reported every file clean, and the ScanCore pipeline reported every file infected. Both now report an incomplete scan as not scanned, never as a verdict.
  • Scanning several files at once returned only the last file's verdict, so an infected file followed by a clean one was reported clean. Every file counts now.
  • Large files over 100M were skipped by ClamAV and reported clean. Size limits now scale with the file, and a limit reached is reported as not scanned.
  • Root code execution through a temporary folder. An unprivileged account could plant a module in the shared dependency scratch folder that then ran as root during --setup. Each account now uses a private folder it owns.
  • A shared LibreOffice profile. An unsandboxed document conversion used a profile folder in /tmp that any account could create first, and a profile can carry macros. Each conversion now gets a private profile that is removed afterwards.
  • Dangerous formats. The dangerous-format check missed formats written without their leading dot, so a dangerous format an administrator allowed could pass. Both spellings are checked everywhere.
  • Deleted originals. A conversion whose output had the same name and extension as its input deleted the original. It is now refused with error 14005.
  • Scanner output leaking server details. Raw scanner output, which named server paths and the account, no longer reaches users.
  • Every dependency command is sandboxed. su is replaced by a fork that drops privilege and cannot regain it, and network tools are given a pinned address rather than a resolver.

✨ What's New

The Engine (Diablo Engine 2)

  • The Engine lives in Resources/Engine and calls no application code. The linters enforce that boundary.
  • The kernel is a file of its own, Resources/Kernel/kernel.php, and is pinned exactly.
  • The application's contract lives in Resources/Contract, beside the Engine, not inside it.
  • The Pipeline Core is part of the Engine. Accepting a pipeline is one line in the contract.
  • All 16 pipelines are detachable. Virus scanning and file handling are pipelines too.
  • New Environment Manager: a root-owned repair process that runs on a timer.
  • The Engine owns its commands: --setup, --config, --pipeline, the listener and the managers.

Features

  • Download a file from a URL. This is off by default, with configurable private address ranges.
  • A playlist source URL field for streams.
  • --Logo URL-- setting.
  • Five new 3D model output formats.
  • Python 3.14, and PyMeshLab installed with pip on both x86 and arm64.

Command line

  • Every command returns an exit status: 0 for success, 1 for a failure, 2 for an argument that wasn't understood.
  • Arguments are case insensitive.

Interface

  • Bundled Dropzone upgraded to 6.2.0.
  • The dropdown arrow follows the reading direction.
  • The file list follows the colour scheme.
  • Upload and image-format menu fixes.
  • Every placeholder page is valid HTML and declares its language.

Supply chain & policy

Quality control

  • Two independent linters, in Python and Bash, cross-check each other. The Python linter runs 25 checks, and every check is proven against planted faults.
  • A new documentation checker.
  • The error catalogue matches the code.

⚠️ Upgrade Notes

  • Custom interfaces must be updated. Interfaces are pinned exactly and are now v4.0.0. The Wide interface has been removed. Language packs are unchanged at v3.9.3.
  • Your existing config.php still works. $ConfigVersion stays v3.9.6. Some settings were retired and are simply ignored if present: the nineteen Minimum*Version settings, UsePatchedDocumentEngine and DocumentEngineSleepTimer. unoconv is no longer used. Run php convertCore.php --config --repair to add the new settings.
  • Set $ScanCoreChunkSize = 67108864; if your config.php still carries the old 134217928. A larger chunk is reduced at scan time and logged as a warning.
  • Docker needs SYS_ADMIN. It is required for the sandbox. Without it, conversions are refused rather than run unprotected.
  • Restart the listener after upgrading.
  • If you upgraded by copying files over an older release, delete what is left behind:
    • Resources/Engine/Contract
    • Resources/PipelineCore
    • Resources/Unoconv
    • Documentation/Build/hrconvert2-test-addresses.php
    • Documentation/CREATING_CONVERSION_PIPELINES_EXAMPLE.txt
    • /tmp/.HRConvert2
    • /tmp/HRConvert2-probe

Found a vulnerability? Report it privately from the Security tab. Every report is accepted, and every reporter is credited once the fix ships. See [SECURITY.md](https://github.com/zelon88/HRConvert2/blob/master/Documentation/SECURITY.md).

Don't miss a new HRConvert2 release

NewReleases is sending notifications on new releases.