Repository navigation
Fixes
- JSON-LD XSS via
</script>breakout.MetaHelper::renderJsonLd()usedJSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, so any string value funneled throughsetBreadcrumbs(),setArticle(), orsetOrganization()could contain a literal</script>and break out of the inline JSON-LD script block. A blog/CMS app wiringsetArticle(['headline' => $post->title])was a realistic XSS sink. Flags are nowJSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOTper OWASP "JSON in HTML" guidance —<,>,&,',"are emitted as\uXXXXescapes. - Canonical-URL attribute breakout.
getCanonical()did not HTML-escape the URL when it matched the absolute-URL regex. A developer settingsetCanonical($entity->user_supplied_url)would interpolate raw input intohref="..."via thecsslink template. The URL is now passed throughh()before formatting.
Improvements
- New JSON-LD structured-data API on
MetaHelperfor Schema.org markup:setBreadcrumbs()/getBreadcrumbs()—BreadcrumbListsetArticle()/getArticle()—ArticlesetOrganization()/getOrganization()—Organizationwith global config merge support
Usage
// Breadcrumbs
$this->Meta->setBreadcrumbs([
['name' => 'Home', 'url' => '/'],
['name' => 'Blog', 'url' => '/blog'],
['name' => 'My Post'],
]);
// Article
$this->Meta->setArticle([
'headline' => 'My Article',
'author' => 'John Doe',
'datePublished' => '2026-03-19',
]);
// Organization (supports global config)
$this->Meta->setOrganization([
'name' => 'Acme Inc',
'url' => 'https://acme.com',
]);
// Automatically included in out()
echo $this->Meta->out();JSON-LD is pretty-printed in debug mode for readability.
Full Changelog: 1.1.1...1.2.0