fix(env): validate Docker-compatible variable keys

Add shared environment variable key validation and normalization for Livewire forms and models, allowing Docker-compatible keys while rejecting invalid entries such as keys containing equals signs. Also quote Railpack build environment and secret arguments safely.
This commit is contained in:
Andras Bacsai
2026-05-11 15:43:09 +02:00
parent d5946dcfca
commit b5ff124446
11 changed files with 294 additions and 57 deletions
+67
View File
@@ -82,6 +82,12 @@ class ValidationPatterns
*/
public const DOCKER_NETWORK_PATTERN = '/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/';
/**
* Pattern for Docker-compatible environment variable keys.
* Docker environment entries are KEY=value strings, so keys must be non-empty and cannot contain '=' or NUL.
*/
public const ENVIRONMENT_VARIABLE_KEY_PATTERN = '/\A[^=\x00]+\z/u';
/**
* Pattern for SQL-safe unquoted database identifiers (usernames, database names).
* Allows letters, digits, underscore; first char must be letter or underscore.
@@ -96,6 +102,67 @@ class ValidationPatterns
*/
public const DB_PASSWORD_PATTERN = '/^[A-Za-z0-9!@#%^*()_+\-=\[\]{}:,.?\/~]+$/';
/**
* Normalize environment variable keys before validation and storage.
*/
public static function normalizeEnvironmentVariableKey(string $value): string
{
return str($value)->trim()->value;
}
/**
* Get validation rules for environment variable keys.
*/
public static function environmentVariableKeyRules(bool $required = true, int $maxLength = 255): array
{
$rules = [];
if ($required) {
$rules[] = 'required';
} else {
$rules[] = 'nullable';
}
$rules[] = 'string';
$rules[] = "max:$maxLength";
$rules[] = 'regex:'.self::ENVIRONMENT_VARIABLE_KEY_PATTERN;
return $rules;
}
/**
* Get validation messages for environment variable key fields.
*/
public static function environmentVariableKeyMessages(string $field = 'key', string $label = 'key'): array
{
return [
"{$field}.regex" => "The {$label} must be a non-empty Docker-compatible environment variable key and cannot contain '=' or NUL characters.",
"{$field}.max" => "The {$label} may not be greater than :max characters.",
];
}
/**
* Check if a string is a valid environment variable key.
*/
public static function isValidEnvironmentVariableKey(string $value): bool
{
return preg_match(self::ENVIRONMENT_VARIABLE_KEY_PATTERN, $value) === 1;
}
/**
* Normalize and validate an environment variable key.
*/
public static function validatedEnvironmentVariableKey(string $value, string $label = 'key'): string
{
$key = self::normalizeEnvironmentVariableKey($value);
if (! self::isValidEnvironmentVariableKey($key)) {
throw new \InvalidArgumentException(self::environmentVariableKeyMessages(label: $label)['key.regex']);
}
return $key;
}
/**
* Get validation rules for database identifier fields (username, database name).
*