Skip to content

Commit 1e7d1d0

Browse files
committed
Changed the way requests that don't match any elements generate the canonicalUrl, to avoid potentially executing injected Twig code
Signed-off-by: Andrew Welch <andrew@nystudio107.com>
1 parent d39f4e9 commit 1e7d1d0

File tree

4 files changed

+72
-29
lines changed

4 files changed

+72
-29
lines changed

Diff for: src/helpers/DynamicMeta.php

+6
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,12 @@ public static function getLocalizedUrls(string $uri = null, int $siteId = null):
500500
Craft::error($e->getMessage(), __METHOD__);
501501
}
502502
}
503+
// Strip any query string params, and make sure we have an absolute URL with protocol
504+
if ($urlParams === null) {
505+
$url = UrlHelper::stripQueryString($url);
506+
}
507+
$url = UrlHelper::absoluteUrlWithProtocol($url);
508+
503509
$url = $url ?? '';
504510
$language = $site->language;
505511
$ogLanguage = str_replace('-', '_', $language);

Diff for: src/models/MetaGlobalVars.php

+14
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,20 @@ public function __construct(array $config = [])
199199
parent::__construct($config);
200200
}
201201

202+
/**
203+
* @inheritdoc
204+
*/
205+
public function init()
206+
{
207+
parent::init();
208+
// If we have potentially unsafe Twig code, strip it out
209+
if (!empty($this->canonicalUrl)) {
210+
if (strpos($this->canonicalUrl, 'craft.app.request.pathInfo') !== false) {
211+
$this->canonicalUrl = '{seomatic.helper.safeCanonicalUrl()}';
212+
}
213+
}
214+
}
215+
202216
/**
203217
* @inheritdoc
204218
*/

Diff for: src/seomatic-config/globalmeta/GlobalVars.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
'seoImageWidth' => '',
2727
'seoImageHeight' => '',
2828
'seoImageDescription' => '',
29-
'canonicalUrl' => '{{ craft.app.request.pathInfo | striptags }}',
29+
'canonicalUrl' => '{seomatic.helper.safeCanonicalUrl()}',
3030
'robots' => 'all',
3131
'ogType' => 'website',
3232
'ogTitle' => '{seomatic.meta.seoTitle}',

Diff for: src/services/Helper.php

+51-28
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,23 @@
1111

1212
namespace nystudio107\seomatic\services;
1313

14+
use nystudio107\seomatic\helpers\UrlHelper;
1415
use nystudio107\seomatic\Seomatic;
1516
use nystudio107\seomatic\helpers\DynamicMeta as DynamicMetaHelper;
1617
use nystudio107\seomatic\helpers\ImageTransform as ImageTransformHelper;
1718
use nystudio107\seomatic\helpers\Schema as SchemaHelper;
1819
use nystudio107\seomatic\helpers\Text as TextHelper;
1920

21+
use Craft;
2022
use craft\base\Component;
2123
use craft\elements\Asset;
2224
use craft\elements\db\MatrixBlockQuery;
2325
use craft\elements\db\TagQuery;
2426
use craft\helpers\Template;
25-
use craft\helpers\UrlHelper;
2627
use craft\web\twig\variables\Paginate;
2728

29+
use yii\base\InvalidConfigException;
30+
2831
/**
2932
* @author nystudio107
3033
* @package Seomatic
@@ -38,9 +41,28 @@ class Helper extends Component
3841
// Public Methods
3942
// =========================================================================
4043

44+
/**
45+
* Return the canonical URL for the request, with the query string stripped
46+
*
47+
* @return string
48+
*/
49+
public static function safeCanonicalUrl(): string
50+
{
51+
$url = '';
52+
try {
53+
$url = Craft::$app->getRequest()->getPathInfo();
54+
} catch (InvalidConfigException $e) {
55+
Craft::error($e->getMessage(), __METHOD__);
56+
}
57+
$url = UrlHelper::stripQueryString($url);
58+
59+
return UrlHelper::absoluteUrlWithProtocol($url);
60+
}
61+
4162
/**
4263
* Paginate based on the passed in Paginate variable as returned from the
43-
* Twig {% paginate %} tag: https://docs.craftcms.com/v3/templating/tags/paginate.html#the-pageInfo-variable
64+
* Twig {% paginate %} tag:
65+
* https://docs.craftcms.com/v3/templating/tags/paginate.html#the-pageInfo-variable
4466
*
4567
* @param Paginate $pageInfo
4668
*/
@@ -86,8 +108,8 @@ public static function truncateOnWord($string, $length, $substring = '…'): str
86108
* Return a list of localized URLs that are in the current site's group
87109
* The current URI is used if $uri is null. Similarly, the current site is
88110
* used if $siteId is null.
89-
* The resulting array of arrays has `id`, `language`, `ogLanguage`, `hreflangLanguage`,
90-
* and `url` as keys.
111+
* The resulting array of arrays has `id`, `language`, `ogLanguage`,
112+
* `hreflangLanguage`, and `url` as keys.
91113
*
92114
* @param string|null $uri
93115
* @param int|null $siteId
@@ -131,6 +153,7 @@ public static function seoFileLink($url, $robots = '', $canonical = '', $inline
131153
.$inlineStr
132154
.'/'
133155
.$fileName;
156+
134157
return Template::raw(UrlHelper::siteUrl($seoFileLink));
135158
}
136159

@@ -238,6 +261,30 @@ public static function extractSummary($text = '', $useStopWords = true): string
238261
return TextHelper::extractSummary($text, $useStopWords);
239262
}
240263

264+
/**
265+
* Return a flattened, indented menu of the given $path
266+
*
267+
* @param string $path
268+
*
269+
* @return array
270+
*/
271+
public static function getTypeMenu($path): array
272+
{
273+
return SchemaHelper::getTypeMenu($path);
274+
}
275+
276+
/**
277+
* Return a single menu of schemas starting at $path
278+
*
279+
* @param string $path
280+
*
281+
* @return array
282+
*/
283+
public static function getSingleTypeMenu($path): array
284+
{
285+
return SchemaHelper::getSingleTypeMenu($path);
286+
}
287+
241288
/**
242289
* Transform the $asset for social media sites in $transformName and
243290
* optional $siteId
@@ -282,28 +329,4 @@ public function socialTransformHeight($asset, string $transformName = '', $siteI
282329
{
283330
return ImageTransformHelper::socialTransformHeight($asset, $transformName, $siteId);
284331
}
285-
286-
/**
287-
* Return a flattened, indented menu of the given $path
288-
*
289-
* @param string $path
290-
*
291-
* @return array
292-
*/
293-
public static function getTypeMenu($path): array
294-
{
295-
return SchemaHelper::getTypeMenu($path);
296-
}
297-
298-
/**
299-
* Return a single menu of schemas starting at $path
300-
*
301-
* @param string $path
302-
*
303-
* @return array
304-
*/
305-
public static function getSingleTypeMenu($path): array
306-
{
307-
return SchemaHelper::getSingleTypeMenu($path);
308-
}
309332
}

0 commit comments

Comments
 (0)