diff --git a/features.module b/features.module
index 681f05a..55b8a96 100644
--- a/features.module
+++ b/features.module
@@ -28,14 +28,10 @@ function features_help($route_name, RouteMatchInterface $route_match) {
 function features_file_download($uri) {
   $scheme = file_uri_scheme($uri);
   $target = file_uri_target($uri);
-  $session = \Drupal::request()->getSession();
-  if (isset($session)) {
-    $archive_name = $session->get('features_download');
-    if ($scheme == 'temporary' && $target == $archive_name) {
-      return array(
-        'Content-disposition' => 'attachment; filename="' . $archive_name . '"',
-      );
-    }
+  if ($scheme == 'temporary' && $target) {
+    return array(
+      'Content-disposition' => 'attachment; filename="' . $target . '"',
+    );
   }
 }
 
diff --git a/features.routing.yml b/features.routing.yml
index 3fc9c3c..aac9c01 100644
--- a/features.routing.yml
+++ b/features.routing.yml
@@ -1,5 +1,5 @@
 features.export_download:
-  path: '/admin/config/development/configuration/features/download'
+  path: '/admin/config/development/configuration/features/download/{uri}'
   defaults:
     _controller: 'Drupal\features\Controller\FeaturesController::downloadExport'
   requirements:
diff --git a/modules/features_ui/src/Form/FeaturesEditForm.php b/modules/features_ui/src/Form/FeaturesEditForm.php
index f74a83d..0969214 100644
--- a/modules/features_ui/src/Form/FeaturesEditForm.php
+++ b/modules/features_ui/src/Form/FeaturesEditForm.php
@@ -133,7 +133,7 @@ class FeaturesEditForm extends FormBase {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state, $featurename = '') {
-    $session = \Drupal::request()->getSession();
+    $session = $this->getRequest()->getSession();
     $this->allowConflicts = FALSE;
     if (isset($session)) {
       $this->allowConflicts = $session->get('features_allow_conflicts', FALSE);
diff --git a/src/Controller/FeaturesController.php b/src/Controller/FeaturesController.php
index 8f131b2..895ab05 100644
--- a/src/Controller/FeaturesController.php
+++ b/src/Controller/FeaturesController.php
@@ -7,10 +7,12 @@
 
 namespace Drupal\features\Controller;
 
+use Drupal\Core\Access\CsrfTokenGenerator;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\system\FileDownloadController;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 
 /**
  * Returns responses for config module routes.
@@ -25,11 +27,20 @@ class FeaturesController implements ContainerInjectionInterface {
   protected $fileDownloadController;
 
   /**
+   * The CSRF token generator.
+   *
+   * @var \Drupal\Core\Access\CsrfTokenGenerator
+   */
+  protected $csrfToken;
+
+
+  /**
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      new FileDownloadController()
+      new FileDownloadController(),
+      $container->get('csrf_token')
     );
   }
 
@@ -38,19 +49,33 @@ class FeaturesController implements ContainerInjectionInterface {
    *
    * @param \Drupal\system\FileDownloadController $file_download_controller
    *   The file download controller.
+   * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
+   *   The CSRF token generator.
    */
-  public function __construct(FileDownloadController $file_download_controller) {
+  public function __construct(FileDownloadController $file_download_controller, CsrfTokenGenerator $csrf_token) {
     $this->fileDownloadController = $file_download_controller;
+    $this->csrfToken = $csrf_token;
   }
 
   /**
    * Downloads a tarball of the site configuration.
+   *
+   * @param string $uri
+   *   The URI to download.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request.
+   *
+   * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
+   *   The downloaded file.
    */
-  public function downloadExport() {
-    $session = \Drupal::request()->getSession();
-    if (isset($session)) {
-      $archive_name = $session->get('features_download');
-      $request = new Request(array('file' => $archive_name));
+  public function downloadExport($uri, Request $request) {
+    if ($uri) {
+      // @todo Simplify once https://www.drupal.org/node/2630920 is solved.
+      if (!$this->csrfToken->validate($request->query->get('token'), $uri)) {
+        throw new AccessDeniedHttpException();
+      }
+
+      $request = new Request(array('file' => $uri));
       return $this->fileDownloadController->download($request, 'temporary');
     }
   }
diff --git a/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php b/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
index bbc2ddd..91ed2fd 100644
--- a/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
+++ b/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
@@ -9,11 +9,14 @@
 namespace Drupal\features\Plugin\FeaturesGeneration;
 
 use Drupal\Component\Serialization\Yaml;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Url;
 use Drupal\features\FeaturesGenerationMethodBase;
 use Drupal\Core\Archiver\ArchiveTar;
 use Drupal\Core\Config\InstallStorage;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\features\FeaturesBundleInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Class for generating a compressed archive of packages.
@@ -25,7 +28,33 @@ use Drupal\features\FeaturesBundleInterface;
  *   description = @Translation("Generate packages and optional profile as a compressed archive for download."),
  * )
  */
-class FeaturesGenerationArchive extends FeaturesGenerationMethodBase {
+class FeaturesGenerationArchive extends FeaturesGenerationMethodBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The CSRF token generator.
+   *
+   * @var \Drupal\Core\Access\CsrfTokenGenerator
+   */
+  protected $csrfToken;
+
+  /**
+   * Creates a new FeaturesGenerationArchive instance.
+   *
+   * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
+   *   The CSRF token generator.
+   */
+  public function __construct(\Drupal\Core\Access\CsrfTokenGenerator $csrf_token) {
+    $this->csrfToken = $csrf_token;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $container->get('csrf_token')
+    );
+  }
 
   /**
    * The package generation method id.
@@ -241,11 +270,7 @@ class FeaturesGenerationArchive extends FeaturesGenerationMethodBase {
    */
   public function exportFormSubmit(array &$form, FormStateInterface $form_state) {
     // Redirect to the archive file download.
-    $session = \Drupal::request()->getSession();
-    if (isset($session)) {
-      $session->set('features_download', $this->archiveName);
-    }
-    $form_state->setRedirect('features.export_download');
+    $form_state->setRedirect('features.export_download', ['uri' => $this->archiveName, 'token' => $this->csrfToken->get($this->archiveName)]);
   }
 
 }
