Does CiviCRM make it possible to specify which directories are private and which are public-accessible?
This is currently not possible in CiviCRM. A PAAS like Pantheon provides a specific folder for private file uploads and we can't change it to any other folder. However, CiviCRM assumes that the site is either running on Apache (and it can use .htaccess files) or that custom NGINX rules can be set. This is an unreasonable expectation.
CiviCRM requires some filepaths to be private and will complain if they're not configured properly: https://civicrm.org/advisory/civi-sa-2014-001-risk-information-disclosure
CiviCRM has hardcoded the filepaths of some things based on the path of CIVICRM_TEMPLATE_COMPILEDIR. The problem is that CIVICRM_TEMPLATE_COMPILEDIR needs to be private but many of the files that CiviCRM is trying to write based on that path need to be publicly available (e.g. dynamically written JS).
An audit of both baseFilePath() and CIVICRM_TEMPLATE_COMPILEDIR: audit-template_compiledir.txt.
Tim provided some technical guidance in another thread #1 (comment 3124):
The references to
CRM_Utils_System_*should become irrelevant if
The references to
::relativeDirectoryalready appear to be irrelevant within
civicrm-core. (The only usage I could find was one which explicitly set its own base.)
The reference to
CRM_Core_Config_Runtimeis more effort. I don't know if it'd work, but my first try would be (a) lookup a path-variable like
Civi::paths()->getVariable('civicrm.log', 'path'), (b) declare the variable in
Civi\Core\Paths, (c) change the relative boot order of
CRM/Core/IDS.phpline feels silly. We should pick one folder! Pointing that at
templates_cmakes as much sense as
uploadDir. (TBH, I'm not sure does anything now that
Config.IDS.inihas been killed.)
CRM/Extension/ClassLoader.phpare very similar to the Smarty use-case (i.e. writing out ephemeral PHP files to take advantage of opcode caching).