appwrite/src/Appwrite/Platform/Installer/Http/Installer/Status.php
Jake Barnby 36bd7a4667 (fix): Address code review security and correctness findings
- Remove var_dump debug calls leaking API keys to stdout
- Stop embedding secret keys in HTML data attributes on upgrades
- Strip sensitive fields from sessionStorage install lock
- Quote hostPath in Docker Compose YAML template
- Remove stack traces from client-facing error responses
- Strip sessionSecret and traces from Status endpoint response
- Fix undefined $input variable (should be $userInput) in CLI install
- Add backtick escaping in .env template to prevent shell injection
- Add 2-hour timeout to isInstallationComplete infinite loop
- Escape user-supplied startCommand in shell strings
- Add LOCK_EX to progress file writes
- Fix typo in Upgrade.php error message
- Remove unused variable in V21 response filter
- Remove dead code in applyLockPayload after sessionStorage sanitization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:58:57 +13:00

65 lines
2.2 KiB
PHP

<?php
namespace Appwrite\Platform\Installer\Http\Installer;
use Appwrite\Platform\Installer\Runtime\State;
use Utopia\Http\Adapter\Swoole\Response;
use Utopia\Platform\Action;
use Utopia\Validator\Text;
class Status extends Action
{
public static function getName(): string
{
return 'installerStatus';
}
public function __construct()
{
$this
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
->setHttpPath('/install/status')
->desc('Poll installation progress')
->param('installId', '', new Text(64, 0), 'Installation ID', true)
->inject('response')
->inject('installerState')
->callback($this->action(...));
}
public function action(string $installId, Response $response, State $state): void
{
$installId = $state->sanitizeInstallId($installId);
if ($installId === '') {
$response->setStatusCode(Response::STATUS_CODE_BAD_REQUEST);
$response->json(['success' => false, 'message' => 'Missing installId']);
return;
}
$path = $state->progressFilePath($installId);
if (!file_exists($path)) {
$response->setStatusCode(Response::STATUS_CODE_NOT_FOUND);
$response->json(['success' => false, 'message' => 'Install not found']);
return;
}
$data = $state->readProgressFile($installId);
if (is_array($data) && isset($data['payload']) && is_array($data['payload'])) {
unset(
$data['payload']['opensslKey'],
$data['payload']['assistantOpenAIKey'],
$data['payload']['opensslKeyHash'],
$data['payload']['assistantOpenAIKeyHash'],
);
}
// Strip sensitive data from step details
if (is_array($data) && isset($data['details']) && is_array($data['details'])) {
foreach ($data['details'] as $stepKey => &$stepDetails) {
if (is_array($stepDetails)) {
unset($stepDetails['sessionSecret'], $stepDetails['trace']);
}
}
unset($stepDetails);
}
$response->json(['success' => true, 'progress' => $data]);
}
}