diff --git a/composer/Plugin/VendorHardening/FileSecurity.php b/composer/Plugin/VendorHardening/FileSecurity.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8bcd6d328dae6ff209cce34d1cbaf6313a424c2
--- /dev/null
+++ b/composer/Plugin/VendorHardening/FileSecurity.php
@@ -0,0 +1,164 @@
+<?php
+
+namespace Drupal\Composer\Plugin\VendorHardening;
+
+/**
+ * Provides file security functions.
+ *
+ * IMPORTANT: This file is duplicated at /lib/Drupal/Component/FileSecurity.
+ * If any change is made here, the same change should be made in the duplicate.
+ * See https://www.drupal.org/project/drupal/issues/3079481.
+ */
+class FileSecurity {
+
+  /**
+   * Writes an .htaccess file in the given directory, if it doesn't exist.
+   *
+   * @param string $directory
+   *   The directory.
+   * @param bool $deny_public_access
+   *   (optional) Set to FALSE to ensure an .htaccess file for an open and
+   *   public directory. Default is TRUE.
+   * @param bool $force
+   *   (optional) Set to TRUE to force overwrite an existing file.
+   *
+   * @return bool
+   *   TRUE if the file already exists or was created. FALSE otherwise.
+   */
+  public static function writeHtaccess($directory, $deny_public_access = TRUE, $force = FALSE) {
+    return self::writeFile($directory, '/.htaccess', self::htaccessLines($deny_public_access), $force);
+  }
+
+  /**
+   * Returns the standard .htaccess lines that Drupal writes.
+   *
+   * @param bool $deny_public_access
+   *   (optional) Set to FALSE to return the .htaccess lines for an open and
+   *   public directory that allows Apache to serve files, but not execute code.
+   *   The default is TRUE, which returns the .htaccess lines for a private and
+   *   protected directory that Apache will deny all access to.
+   *
+   * @return string
+   *   The desired contents of the .htaccess file.
+   *
+   * @see file_save_htaccess()
+   */
+  public static function htaccessLines($deny_public_access = TRUE) {
+    $lines = static::htaccessPreventExecution();
+
+    if ($deny_public_access) {
+      $lines = static::denyPublicAccess() . "\n\n$lines";
+    }
+
+    return $lines;
+  }
+
+  /**
+   * Returns htaccess directives to deny execution in a given directory.
+   *
+   * @return string
+   *   Apache htaccess directives to prevent execution of files in a location.
+   */
+  protected static function htaccessPreventExecution() {
+    return <<<EOF
+# Turn off all options we don't need.
+Options -Indexes -ExecCGI -Includes -MultiViews
+
+# Set the catch-all handler to prevent scripts from being executed.
+SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
+<Files *>
+  # Override the handler again if we're run later in the evaluation list.
+  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
+</Files>
+
+# If we know how to do it safely, disable the PHP engine entirely.
+<IfModule mod_php5.c>
+  php_flag engine off
+</IfModule>
+<IfModule mod_php7.c>
+  php_flag engine off
+</IfModule>
+EOF;
+  }
+
+  /**
+   * Returns htaccess directives to block all access to a given directory.
+   *
+   * @return string
+   *   Apache htaccess directives to block access to a location.
+   */
+  protected static function denyPublicAccess() {
+    return <<<EOF
+# Deny all requests from Apache 2.4+.
+<IfModule mod_authz_core.c>
+  Require all denied
+</IfModule>
+
+# Deny all requests from Apache 2.0-2.2.
+<IfModule !mod_authz_core.c>
+  Deny from all
+</IfModule>
+EOF;
+  }
+
+  /**
+   * Writes a web.config file in the given directory, if it doesn't exist.
+   *
+   * @param string $directory
+   *   The directory.
+   * @param bool $force
+   *   (optional) Set to TRUE to force overwrite an existing file.
+   *
+   * @return bool
+   *   TRUE if the file already exists or was created. FALSE otherwise.
+   */
+  public static function writeWebConfig($directory, $force = FALSE) {
+    return self::writeFile($directory, '/web.config', self::webConfigLines(), $force);
+  }
+
+  /**
+   * Returns the standard web.config lines for security.
+   *
+   * @return string
+   *   The contents of the web.config file.
+   */
+  public static function webConfigLines() {
+    return <<<EOT
+<configuration>
+  <system.webServer>
+    <authorization>
+      <deny users="*">
+    </authorization>
+  </system.webServer>
+</configuration>
+EOT;
+  }
+
+  /**
+   * Writes the contents to the file in the given directory.
+   *
+   * @param string $directory
+   *   The directory to write to.
+   * @param string $filename
+   *   The file name.
+   * @param string $contents
+   *   The file contents.
+   * @param bool $force
+   *   TRUE if we should force the write over an existing file.
+   *
+   * @return bool
+   *   TRUE if writing the file was successful.
+   */
+  protected static function writeFile($directory, $filename, $contents, $force) {
+    $file_path = $directory . DIRECTORY_SEPARATOR . $filename;
+    // Don't overwrite if the file exists unless forced.
+    if (file_exists($file_path) && !$force) {
+      return TRUE;
+    }
+    if (file_exists($directory) && is_writable($directory) && file_put_contents($file_path, $contents)) {
+      return @chmod($file_path, 0444);
+    }
+    return FALSE;
+  }
+
+}
diff --git a/composer/Plugin/VendorHardening/VendorHardeningPlugin.php b/composer/Plugin/VendorHardening/VendorHardeningPlugin.php
index cf049003669f24480d82552dfa3ed7be8fa8e399..7e36e0e9e18440ea6dd35bdd07fb91e198fcc2ce 100644
--- a/composer/Plugin/VendorHardening/VendorHardeningPlugin.php
+++ b/composer/Plugin/VendorHardening/VendorHardeningPlugin.php
@@ -11,7 +11,6 @@
 use Composer\Util\Filesystem;
 use Composer\Script\Event;
 use Composer\Installer\PackageEvents;
-use Drupal\Component\FileSecurity\FileSecurity;
 
 /**
  * A Composer plugin to clean out your project's vendor directory.
diff --git a/composer/Plugin/VendorHardening/composer.json b/composer/Plugin/VendorHardening/composer.json
index 3bafc9a7858da7637df76686567d9913d71fbc32..da71b12a1f3f362bc9119aedbe781fc47026877e 100644
--- a/composer/Plugin/VendorHardening/composer.json
+++ b/composer/Plugin/VendorHardening/composer.json
@@ -15,7 +15,6 @@
   },
   "require": {
     "php": ">=7.0.8",
-    "composer-plugin-api": "^1.1",
-    "drupal/core-file-security": "^8.8"
+    "composer-plugin-api": "^1.1"
   }
 }
diff --git a/core/lib/Drupal/Component/FileSecurity/FileSecurity.php b/core/lib/Drupal/Component/FileSecurity/FileSecurity.php
index efe1119c2707aa01a0bb11e98042e796e79f0158..8673d3c2ab29a6b20e1645ce8675f1f00f230cd1 100644
--- a/core/lib/Drupal/Component/FileSecurity/FileSecurity.php
+++ b/core/lib/Drupal/Component/FileSecurity/FileSecurity.php
@@ -4,6 +4,10 @@
 
 /**
  * Provides file security functions.
+ *
+ * IMPORTANT: This file is duplicated at /composer/Plugin/VendorHardening.
+ * If any change is made here, the same change should be made in the duplicate.
+ * See https://www.drupal.org/project/drupal/issues/3079481
  */
 class FileSecurity {