Issue #3370043 by catch, Chi: Asset controller should validate filename prefix

merge-requests/4276/head
Lee Rowlands 2023-06-27 06:12:34 +10:00
parent cd9fed87f0
commit 2e3dea7a2b
No known key found for this signature in database
GPG Key ID: 2B829A3DF9204DC4
3 changed files with 22 additions and 0 deletions

View File

@ -133,6 +133,8 @@ class JsCollectionOptimizerLazy implements AssetCollectionGroupOptimizerInterfac
'scope' => $js_asset['scope'] === 'header' ? 'header' : 'footer',
'delta' => "$order",
] + $query_args;
// Add a filename prefix to mitigate ad blockers which can block
// any script beginning with 'ad'.
$filename = 'js_' . $this->generateHash($js_asset) . '.js';
$uri = 'assets://js/' . $filename;
$js_assets[$order]['data'] = $this->fileUrlGenerator->generateString($uri) . '?' . UrlHelper::buildQuery($query);

View File

@ -136,6 +136,10 @@ abstract class AssetControllerBase extends FileDownloadController {
throw new BadRequestHttpException('The libraries to include must be passed as a query argument');
}
$file_parts = explode('_', basename($file_name, '.' . $this->fileExtension), 2);
// Ensure the filename is correctly prefixed.
if ($file_parts[0] !== $this->fileExtension) {
throw new BadRequestHttpException('The filename prefix must match the file extension');
}
// The hash is the second segment of the filename.
if (!isset($file_parts[1])) {

View File

@ -163,6 +163,9 @@ class AssetOptimizationTest extends BrowserTestBase {
$session->visit($this->invalidExclude($url));
$this->assertSession()->statusCodeEquals(400);
$session->visit($this->replaceFileNamePrefix($url));
$this->assertSession()->statusCodeEquals(400);
$session->visit($this->setInvalidLibrary($url));
$this->assertSession()->statusCodeEquals(200);
@ -210,6 +213,19 @@ class AssetOptimizationTest extends BrowserTestBase {
return $this->getAbsoluteUrl(implode('_', $parts));
}
/**
* Replaces the filename prefix in the given URL.
*
* @param string $url
* The source URL.
*
* @return string
* The URL with the file name prefix replaced.
*/
protected function replaceFileNamePrefix(string $url): string {
return str_replace(['/css_', '/js_'], '/xyz_', $url);
}
/**
* Replaces the 'include' entry in the given URL with an invalid value.
*