Skip to content

v2.1.0 – Strange New Worlds

Choose a tag to compare

@github-actions github-actions released this 29 Sep 20:33
· 2 commits to main since this release

Qbix Server v2.1.0 — Strange New Worlds

v2.0 was a mesh-networked runtime. v2.1 makes it production-ready: every major PHP framework runs unmodified, the control panel manages apps end-to-end, mobile apps can be built and distributed for iOS and Android from the panel, and nine security audit passes harden the entire stack.

The mesh layer is still there — every v2.0 feature works unchanged. v2.1 adds the framework compat layer, a rebuilt control panel, mobile build scaffolding, and a significant number of security fixes.

Framework Compatibility

The compat source transform now handles output buffer protection, SAPI detection, and 27 shimmed PHP functions. Frameworks like Laravel, Symfony, WordPress, Drupal, CakePHP, Yii, and Mezzio run out of the box — no code changes, no plugins, no extensions.

# Drop a Laravel app in and go
php qbixserver.php --root=my-laravel-app/public --port=8080

Source Transform

The rewriter intercepts calls that would break under Qbix's execution model:

  • ob_end_flush(), ob_end_clean(), ob_get_clean(), ob_get_level() are shimmed so frameworks that drain output buffers in a loop don't infinite-loop against Qbix's protected buffer.
  • php_sapi_name() returns 'cli-server' instead of 'cli'. The PHP_SAPI constant is replaced via a context-aware constant engine that skips qualified references like SomeClass::PHP_SAPI.
  • All shimmed calls are emitted fully qualified (\Q_WebServer_Compat::_header(...)) so they resolve correctly inside namespaced framework code. The v2.0 rewriter omitted the leading backslash, which broke every Symfony, Laravel, and Drupal response.

13 Framework Presets

Built-in presets for Laravel, Symfony, WordPress, Drupal, CakePHP, CodeIgniter, Yii, Mezzio, Slim, Joomla, Magento, Nextcloud, and ownCloud. Each preset sets the front controller, upload limits, memory limits, and session settings appropriate for the framework.

12 Boot Adapters

Boot adapters automatically detect and bootstrap each framework. A Custom adapter allows user-specified boot callables.

Performance

Benchmarked against PHP's built-in development server:

Framework php -S Qbix Server Speedup
Laravel 190 req/s 653 req/s 3.4×
Drupal 404 req/s 1,636 req/s 4.0×
CakePHP 905 req/s 1,790 req/s 2.0×
Mezzio 1,580 req/s 2,337 req/s 1.5×

See BENCHMARKS.md for full methodology.

Control Panel

App Management

Create, delete, start, stop, and configure apps from the panel. Domain assignment, SSL cert provisioning, and framework detection are integrated into the app creation flow. The panel also manages WordPress and Drupal plugin/module installation through their respective CLIs.

Cache Clearing

Append ?Q.clearCache to any URL to clear all caches — opcode, static file, precompression, and image — for that app. During development this replaces the cycle of clearing APC, restarting workers, and purging the image cache separately.

Script Modules

The panel's JavaScript is organized into modules with a loader, replacing the inline scripts that grew to several thousand lines in v2.0. The module system loads only the code needed for the active tab.

Mobile Build and Distribution

The control panel can scaffold, build, and package native iOS and Android apps.

Scaffolding

Click Prepare with a platform selected and the panel generates a complete native project:

  • iOS: Swift source files + project.yml for xcodegen. PhpBridge.swift starts PHP via posix_spawn, TransportManager.swift handles BLE/MC/LAN, BackgroundKeepAlive.swift maintains the silent audio session.
  • Android: Kotlin source files + Gradle (Kotlin DSL). PhpBridge.kt extracts the binary from APK assets and runs it via ProcessBuilder, TransportManager.kt handles BLE/LAN, QbixServerService.kt runs the Foreground Service.

Both include the GATT service UUIDs, chunking protocol, and mesh handshake integration.

Building

Click Build and the panel runs xcodebuild or ./gradlew assembleRelease. CI produces qbixserver-ios-arm64 and qbixserver-android-arm64 micro binaries via static-php-cli, with Android NDK cross-compilation.

Distribution

iOS apps are archived and uploaded to App Store Connect via the Xcode Organizer or xcodebuild -exportArchive. TestFlight handles beta distribution (25 internal testers without review, 10,000 external testers with review). Ad Hoc provisioning supports direct distribution to up to 100 registered devices.

Android apps are signed with a release keystore and uploaded to the Google Play Console as an AAB. The Play Console offers internal (100 testers, no review), closed (invite-only), and open testing tracks before production. Signed APKs can also be distributed directly for sideloading or alternative stores.

See mobile/iOS.md and mobile/Android.md for full walkthroughs.

Security Hardening

Nine audit passes reviewed Panel.php (~7,000 lines), TransportManager.swift (~860 lines), and TransportManager.kt (~680 lines). Each pass found progressively fewer issues — 7, then 3, then 1 — confirming convergence.

XSS Prevention

All innerHTML assignments in the Nearby tab now escape API-returned data through escHtml(). Previously, a peer could set its mesh name to <img onerror=...> and have it rendered unsanitized in the control panel. Fixed in: mesh identity display, routing table rows, peer connection status, script selector options, attestation labels, and attestation signer fields.

Path Traversal

basename() is applied to directory names from user input in apiQbixNpm, apiFrameworkPkgDownload, and framework package endpoints. Without this, a target value of ../../etc could traverse outside the expected directory.

Shell Injection

escapeshellarg() is applied to all user-supplied paths passed to shell commands. This covers the WordPress CLI path (wp) and Drupal CLI path (drush) in six locations across apiFrameworkPackages, apiFrameworkPkgAction, and apiFrameworkRun. A crafted CLI path like /usr/bin/wp; rm -rf / would previously execute the injected command.

Authentication

apiChangePassword and apiLogout now check the Authorization: Bearer header in addition to X-Panel-Token and cookies, matching the existing checkAuth logic. API clients authenticating via Bearer header could previously not change their password or log out — the token lookup returned empty and the operation silently failed or invalidated the wrong session.

BLE SSRF

Both the iOS and Android TransportManagers now reject BLE-received HTTP request paths that don't start with /. Without this check, a crafted BLE request could use the path as a userinfo@host trick — the HTTP client would interpret user:pass@evil.com/path as a request to evil.com — turning the local server into an open proxy reachable over Bluetooth.

// iOS fix
guard parsed.path.hasPrefix("/") else {
    sendBLEResponse("HTTP/1.1 400 Bad Request\r\n..."
        .data(using: .utf8)!, to: central)
    return
}
// Android fix
if (!path.startsWith("/")) return@submit

MultipeerConnectivity Peer Identity

The iOS TransportManager now uses the peer's actual mesh_id from the ECDH handshake when relaying MultipeerConnectivity messages to PHP, instead of the MC displayName. The MC display name is an arbitrary string set by the remote device; the mesh_id is the cryptographic identity established during the handshake. Using the display name meant the PHP server couldn't match MC messages to the correct peer, breaking message routing for any peer whose display name didn't happen to match its mesh ID.

Documentation

Doc What's new
FRAMEWORKS.md All 13 frameworks with presets, adapters, benchmarks
BENCHMARKS.md Framework benchmark section
mobile/README.md Transport layer, GATT protocol, platform requirements
mobile/iOS.md Signing, TestFlight, App Store, Ad Hoc distribution
mobile/Android.md Keystore, Play Store, testing tracks, direct APK
README.md Expanded Mobile section with build/distribute overview

Upgrading from v2.0

No breaking changes. All v2.0 configuration, APIs, and mesh behavior are preserved. The framework compat layer activates only when serving a framework that needs it. The security fixes apply automatically.