diff --git a/package_manager/src/StageBase.php b/package_manager/src/StageBase.php index 9caba25efb2d396de37c0ab199535ba2a852b82e..c51efdfef6c8880070f827eddcc4f97fc02ac771 100644 --- a/package_manager/src/StageBase.php +++ b/package_manager/src/StageBase.php @@ -6,7 +6,7 @@ namespace Drupal\package_manager; use Composer\Semver\VersionParser; use Drupal\Component\Datetime\TimeInterface; -use Drupal\Component\Utility\Crypt; +use Drupal\Component\Utility\Random; use Drupal\Core\Queue\QueueFactory; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslatableMarkup; @@ -344,7 +344,13 @@ abstract class StageBase implements LoggerAwareInterface { // to create a stage directory at around the same time. If an error occurs // while the event is being processed, the stage is marked as available. // @see ::dispatch() - $id = Crypt::randomBytesBase64(); + // We specifically generate a random 32-character alphanumeric name in order + // to guarantee that the the stage ID won't start with -, which could cause + // it to be interpreted as an option if it's used as a command-line + // argument. (For example, + // \Drupal\Component\Utility\Crypt::randomBytesBase64() would be vulnerable + // to this; the stage ID needs to be unique, but not cryptographically so.) + $id = (new Random())->name(32); // Re-acquire the tempstore to ensure that the lock is written by whoever is // actually logged in (or not) right now, since it's possible that the stage // was instantiated (i.e., __construct() was called) by a different session, diff --git a/src/ConsoleUpdateStage.php b/src/ConsoleUpdateStage.php index 4297f800b908009ce8d62e02f9b0ae68b10c4056..101d75fb033bd7709d488022cedb5c918921a884 100644 --- a/src/ConsoleUpdateStage.php +++ b/src/ConsoleUpdateStage.php @@ -280,11 +280,7 @@ class ConsoleUpdateStage extends UpdateStage { * The ID of the current stage. */ protected function triggerPostApply(string $stage_id): void { - // The stage ID needs to be quoted in order to prevent it from being parsed - // as a command-line option if it begins with -, which is a possibility - // because we use \Drupal\Component\Utility\Crypt::randomBytesBase64() to - // generate the stage ID, and the string it returns might begin with -. - $arguments = sprintf('post-apply "%s"', $stage_id); + $arguments = sprintf('post-apply %s', $stage_id); if ($this->isFromWeb) { $arguments .= ' --is-from-web'; }