diff --git a/.htaccess b/.htaccess
index 01c63af981f73adcbdf6c2e3381c1ab6808cee78..974999a9c8f054961516eaea509408243a50dded 100644
--- a/.htaccess
+++ b/.htaccess
@@ -3,7 +3,7 @@
 #
 
 # Protect files and directories from prying eyes.
-<FilesMatch "\.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$">
+<FilesMatch "\.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$">
   <IfModule mod_authz_core.c>
     Require all denied
   </IfModule>
diff --git a/core/modules/system/src/Tests/System/HtaccessTest.php b/core/modules/system/src/Tests/System/HtaccessTest.php
index 0165f196b2d2cda6a37a4be7e6e150aeab6908d4..86563a4d619a33d9861e7f745b084fed9442b79a 100644
--- a/core/modules/system/src/Tests/System/HtaccessTest.php
+++ b/core/modules/system/src/Tests/System/HtaccessTest.php
@@ -86,6 +86,11 @@ protected function getProtectedFiles() {
     foreach ($file_exts_to_allow as $file_ext) {
       $file_paths["$path/access_test.$file_ext"] = 200;
     }
+
+    // Ensure composer.json and composer.lock cannot be accessed.
+    $file_paths["$path/composer.json"] = 403;
+    $file_paths["$path/composer.lock"] = 403;
+
     return $file_paths;
   }
 
diff --git a/core/modules/system/tests/fixtures/HtaccessTest/composer.json b/core/modules/system/tests/fixtures/HtaccessTest/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/modules/system/tests/fixtures/HtaccessTest/composer.lock b/core/modules/system/tests/fixtures/HtaccessTest/composer.lock
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/web.config b/web.config
index 782d4ae50d3b292db78c320adf5d02b32db9fd1a..a0535a10db23e3245063b5390625b46cf349c594 100644
--- a/web.config
+++ b/web.config
@@ -22,7 +22,7 @@
     <rewrite>
       <rules>
         <rule name="Protect files and directories from prying eyes" stopProcessing="true">
-          <match url="\.(engine|inc|install|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$" />
+          <match url="\.(engine|inc|install|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format|composer\.(json|lock))$" />
           <action type="CustomResponse" statusCode="403" subStatusCode="0" statusReason="Forbidden" statusDescription="Access is forbidden." />
         </rule>