Long Twig cache directories can cause failures on some filesystems

Created on 2 November 2015, about 9 years ago
Updated 12 September 2023, about 1 year ago

Problem/Motivation

A D8 install can easily generate extremely lengthy file/directory names when caching Twig templates.

On some scenarios, the maximum length for a path might be limited by the OS:

  • Windows has a maximum path length of 260 characters. Can read more here.
  • If you are in Linux and have the filesystem where you have the site mounted using eCryptfs and its configured to encrypt filenames as well as the file content you will experience this same issue. You can read a little about this limitation here.

To reproduce this issue on Windows, add the following to settings.php.

$settings['file_public_path'] = 'sites/default/files/0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-01'; // That's a 255-char dir name.

Proposed resolution

Update as of #144 going with option #3

Option #3: Trigger a requirement error on windows if the Drupal root is deeper than 100 characters. Use our existing base64 hash and hmac functions so the hashes are half as long to start. Truncate the human-readable template name portion and hash portion of the to a maximum length so the directory names can never be longer than 51 characters. The cache file name itself has already been shortened to 47 characters using the bas64 hmac in the split-off child issue #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily

Update: as of #39, options #2 is the preferred solution.

Option #1: Use the Unicode path prefix (\\?\) on Windows to avoid the 260 character limit (pushes the limit to around 32k which is well above Linux's limit of 4k characters). Unfortunately, PHP's support of these pathnames is limited. (see #16) which would require a much more disruptive fix.

Option #2: Use shorter hashes while retaining the "uniqueness" of these directory and file names. However, the filename hash contains the filemtime() of the containing directory. If, for example, file uploads were compromised and malicious code added to a cached Twig template, the containing directory's filemtime would change and the hash would not match. Using shorter hashes could potentially increase the risk of a compromised file still passing the hash test. (Security review requested).

Also, option #2 does not solve the underlying problem, but hopefully gives us some breathing room. Currently, there are two 64-character hashes in each cached Twig template.

Remaining tasks

As of #12:

  1. not needed since we're using option #2:
  2. Needs security review to ensure that shortened hashs still give enough "uniqueness" for MTimeProtectedFastFileStorage
  3. Needs tests to assert that generated files do no exceed a (somewhat arbitrary) limit
  4. Done:

User interface changes

Adds a new warning when installing Drupal on Windows at a path > 100 characters.

API changes

With option #2, none.

Data model changes

None.

🐛 Bug report
Status

Fixed

Version

8.4 ⚰️

Component
Theme 

Last updated about 12 hours ago

Created by

🇵🇪Peru hatuhay Lima

Live updates comments and jobs are added and updated live.
  • Triaged core major

    There is consensus among core maintainers that this is a major issue. Only core committers should add this tag.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024