47 lines
2.1 KiB
PHP
47 lines
2.1 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* safety-net.php — container-narrow open_basedir allow-list.
|
||
|
|
*
|
||
|
|
* The sibling at /workspace/whp/web-files/includes/safety-net.php is the
|
||
|
|
* panel's allow-list — it includes /docker, /root/whp, /etc/whp, etc.,
|
||
|
|
* because the panel legitimately reads from those.
|
||
|
|
*
|
||
|
|
* Inside this container, the worker has a much smaller set of paths it
|
||
|
|
* needs. Anything outside this list is blocked at the PHP filesystem-
|
||
|
|
* function level (PHP enforces open_basedir in unlink/scandir/fopen/
|
||
|
|
* RecursiveDirectoryIterator/etc. AFTER symlink resolution, so a planted
|
||
|
|
* symlink-to-/proc cannot escape the allow-list).
|
||
|
|
*
|
||
|
|
* HISTORY — the same destruction-bug class that motivated the panel-side
|
||
|
|
* safety-net (whp02 /usr/bin + /etc wipe, 2026-05-28/29) is the reason
|
||
|
|
* this exists. In the container the host /etc /usr /root are not bind-
|
||
|
|
* mounted, but open_basedir gives belt-and-suspenders enforcement
|
||
|
|
* against any extracted-archive symlink walker we add later.
|
||
|
|
*/
|
||
|
|
|
||
|
|
if (function_exists('ini_set')) {
|
||
|
|
// Container-internal paths only. Notable absences:
|
||
|
|
// - /etc, /usr, /var, /root — never written to by this container
|
||
|
|
// - /docker — there is no /docker in this image
|
||
|
|
// - /home — there is no /home in this image
|
||
|
|
$allowed = implode(PATH_SEPARATOR, [
|
||
|
|
'/host', // /host/backup (RO), /host/quarantine, /host/sanitized
|
||
|
|
'/tmp', // tmpfs scratch space
|
||
|
|
'/opt/whp', // WORKDIR + per-run state
|
||
|
|
'/scripts', // our own code
|
||
|
|
'/var/lib/clamav', // ClamAV signature DB
|
||
|
|
'/var/log/clamav', // freshclam log
|
||
|
|
'/etc/freshclam.conf', // single file, read-only
|
||
|
|
'/proc/self', // pid/cgroup introspection
|
||
|
|
]);
|
||
|
|
|
||
|
|
if ((string) ini_get('open_basedir') === '') {
|
||
|
|
@ini_set('open_basedir', $allowed);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Realpath cache tuning matches the panel — open_basedir adds a
|
||
|
|
// realpath() to every fs op, so a bigger cache pays back fast.
|
||
|
|
@ini_set('realpath_cache_size', '512K');
|
||
|
|
@ini_set('realpath_cache_ttl', '600');
|
||
|
|
}
|