title: Passing URL parameters as command line script arguments security considerations
body: <p>I am writing a web app and I need to pass some url parameters as command line arguments to another script. What should I do to avoid security problems? I am using Sympfony's Process to execute the bash command and Laravel to build the app.</p>
  
  <p>Here is some of the code, look into the <code>buildScreenshotCommand</code> to see how I am building the command string and also note that the $urlRequest is filled in using the Laravel's <code>Request $request</code> class:</p>
  
  <pre><code>&lt;?php
  
  namespace App\Logic;
  
  use App\Logic\TimeHelper;
  use App\UrlRequest;
  use Illuminate\Support\Facades\Storage;
  use Symfony\Component\Process\Exception\ProcessFailedException;
  use Symfony\Component\Process\Process;
  
  class Screenshot {
  
      static function take(UrlRequest $urlRequest)
      {
          $name = self::generateName($urlRequest);
          $command = self::buildScreenshotCommand($name, $urlRequest);
  
          $startTime = TimeHelper::milliseconds();
  
          $process = new Process($command);
          $process-&gt;run();
  
          $endTime = TimeHelper::milliseconds();
  
          if (!$process-&gt;isSuccessful())
          {
              throw new ProcessFailedException($process);
          }
  
          $output = $process-&gt;getOutput();
  
          if (trim($output) === '')
          {
              $urlRequest-&gt;successful = 1;
  
              $file = self::uploadToS3($name);
              $urlRequest-&gt;image_url = $file['url'];
              $urlRequest-&gt;file_size = $file['size'];
              $urlRequest-&gt;file_name = $name;
              $urlRequest-&gt;time_it_took_to_take_screenshot_ms = $endTime - $startTime;
  
              if ($urlRequest-&gt;save())
              {
                  return $urlRequest;
              }
          }
          else
          {
              $urlRequest-&gt;error = $output;
              $urlRequest-&gt;save();
          }
  
          return false;
      }
  
      static function uploadToS3($name)
      {
          $name = 'screenshots/' . $name;
  
          Storage::disk('s3')-&gt;put($name, Storage::disk('local')-&gt;get($name), ['visibility' =&gt; 'public']); // upload to S3
  
          $fileSize = Storage::disk('local')-&gt;size($name);
          Storage::disk('local')-&gt;delete($name);
  
          return [
              'url' =&gt; Storage::disk('s3')-&gt;url($name),
              'size' =&gt; $fileSize
          ];
      }
  
      static function generateName($urlRequest)
      {
          $name = time() . rand(10000, 99999);
          $extension = '.png';
  
          if (isset($urlRequest-&gt;pdf) AND $urlRequest-&gt;pdf == 1)
          {
              $extension = '.pdf';
          }
  
          while (UrlRequest::where('file_name', '=', $name . $extension)-&gt;first())
          {
              $name = time() . rand(10000, 99999);
          }
  
          return $name . $extension;
      }
  
      static function buildScreenshotCommand($name, $urlRequest)
      {
          $command = 'cd ' . base_path() . ' &amp;&amp; node puppeteer-screenshots-init.js ';
          $command .= "--url={$urlRequest-&gt;url} ";
  
          $fullPath = storage_path('app') . '/screenshots/' . $name;
  
          $command .= "--path={$fullPath} ";
  
          if (isset($urlRequest-&gt;pdf))
          {
              $command .= "--pdf=true ";
          }
  
          if (isset($urlRequest-&gt;viewport_width))
          {
              $command .= "--viewportWidth={$urlRequest-&gt;viewport_width} ";
          }
  
          if (isset($urlRequest-&gt;mobile))
          {
              $command .= '--mobile=true ';
          }
  
          if (isset($urlRequest-&gt;media_type_print))
          {
              $command .= '--mediaTypePrint=true ';
          }
  
          if (isset($urlRequest-&gt;user_agent))
          {
              $command .= '--userAgent="' . $urlRequest-&gt;user_agent . '" ';
          }
  
          $command .= '2&gt;&amp;1 &amp;';
  
          return $command;
      }
  
  }
  </code></pre>