Add File Manager sub-app (Pro feature) (v2.7.0)

New browse/edit interface for the WordPress install's own files, built
using the installed "WP File Manager" plugin (elFinder-based) as a
functional reference rather than embedding it. Own REST controller
(FileManagerData.php) + Vue page, same pattern as every other sub-app.

Security is the whole point here (highest-risk surface in the plugin —
arbitrary filesystem read/write):
- Root is ABSPATH, manage_options-gated throughout.
- Every client path is resolved via realpath() and checked for root
  containment against the *resolved* path, not string-matched against
  the raw input — catches symlink tricks and encoded traversal that a
  naive "../" check would miss.
- Uploads/new files/renames reject a blocklist of server-executable
  extensions (.php, .cgi, .sh, etc.) — the single most important
  control, since uploading a webshell is the classic exploit path for
  this class of feature.
- Deliberately not built: zip/unzip (zip-slip vulnerability class),
  chmod/permissions editing, cross-directory move/copy.

Gated as a paid feature (riskier than Database Explorer, which is
already paid) — a judgment call flagged to the user, not something they
specified.

Also fixed a real bug found while wiring this up: SubApps.php's
page-level lock doesn't stop someone with manage_options from calling
the REST endpoints directly, bypassing the license check entirely.
File Manager's REST permission callbacks now also check
License::is_feature_available(). The same gap exists in Database
Explorer, Role Editor, and Activity Log's REST controllers and is
flagged as a follow-up task, not fixed here (out of scope for what was
asked, affects three unrelated features).

Verified live via direct REST calls: path traversal blocked (404),
blocked extensions rejected (400), root deletion blocked (400), and a
full create/write/read/rename/delete round trip succeeded cleanly.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
nixpanel
2026-07-05 06:59:24 -05:00
co-authored by Claude Sonnet 5
parent 204c4365e2
commit 15d6060ae3
12 changed files with 1228 additions and 4 deletions
+30
View File
@@ -5,6 +5,36 @@ version bump. Starts at 2.1.0 — earlier history (the theming rebuild,
window chrome/taskbar, Site Editor support, etc.) lives in `git log` and
`PROJECT_STATUS.md`, not reconstructed here.
## [2.7.0] - 2026-07-05
### Added
- New File Manager (`aurora-admin-file-manager`), browsing/editing the
WordPress install's own files — built fresh (not embedding elFinder),
in the spirit of the "WP File Manager" plugin already on this site
(same root, same `manage_options`-only gate). Create/upload/download/
rename/delete files and folders, plus a plain-text editor for
code/config files. A **Pro feature** — the riskiest surface in the
whole plugin (arbitrary read/write access to the site's own PHP files),
so it's gated the same way as Database Explorer.
- Every path a client sends is resolved to a real, `ABSPATH`-contained
path via `realpath()` before any filesystem operation — containment
is checked against the resolved path, not string-matched against the
raw input, so symlink tricks and encoded traversal can't slip past.
- Uploads/new files/renames all reject a blocklist of server-executable
extensions (`.php`, `.phtml`, `.cgi`, `.sh`, etc.) — the single most
important control here, since uploading a webshell is the whole ballgame.
- Deliberately not built: zip/unzip (zip-slip extraction vulnerability),
chmod/permissions editing, and cross-directory move/copy — each is a
meaningfully larger, riskier scope than a first pass warrants.
### Fixed
- File Manager's REST endpoints now also check
`License::is_feature_available('file-manager')`, not just
`manage_options` — found while wiring it up that the page-level lock
alone doesn't stop a direct REST call from bypassing it entirely.
**The same gap exists in Database Explorer, Role Editor, and Activity
Log's REST controllers and is not yet fixed** — flagged as a follow-up.
## [2.6.0] - 2026-07-05
### Added