CVE-2019-7171
Description
A stored-self XSS vulnerability in Croogo through v3.0.5 allows an attacker to inject arbitrary HTML/JavaScript via the Title field in the Blocks editor.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A stored-self XSS vulnerability in Croogo through v3.0.5 allows an attacker to inject arbitrary HTML/JavaScript via the Title field in the Blocks editor.
Vulnerability
A stored-self cross-site scripting (XSS) vulnerability exists in Croogo versions up to and including v3.0.5. The flaw resides in the Title field of the block editing interface at /admin/blocks/blocks/edit/8. User-supplied input is not properly sanitized or encoded before being stored and later rendered, allowing an attacker to inject arbitrary HTML or JavaScript code [1][2].
Exploitation
An attacker must have administrative access to the Croogo backend (specifically the Blocks editor) to exploit this vulnerability. The attacker navigates to the block edit page and enters malicious script content into the Title field. Upon saving, the payload is stored and will execute when any user (including the attacker, hence stored-self XSS) views the affected block in the admin panel [1][2].
Impact
Successful exploitation enables an attacker to execute arbitrary HTML or JavaScript code within the context of the Croogo admin panel. This can lead to actions such as session hijacking, defacement, or further compromise of administrative functions. The attack is self-contained (stored-self) but could be leveraged for broader impact if combined with other weaknesses [1][2][3].
Mitigation
A fix was implemented in commit cafaaabe2cef3d1d83652370e30563e6ad7c4158, which applies output encoding via the h() function to user-supplied fields including $message->title and $message->body [4]. Users should update to a version of Croogo that includes this commit or later. No workaround is documented, and the vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of this publication [1][2][4].
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
croogo/croogoPackagist | < 3.0.7 | 3.0.7 |
Affected products
2Patches
123 files changed · +38 −41
Blocks/src/Template/Admin/Blocks/form.ctp+1 −1 modified@@ -7,7 +7,7 @@ $this->extend('Croogo/Core./Common/admin_edit'); $this->Breadcrumbs->add(__d('croogo', 'Blocks'), ['action' => 'index']); if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($block->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($block->title), $this->request->getRequestTarget()); } if ($this->request->params['action'] == 'add') { $this->Breadcrumbs->add(__d('croogo', 'Add'), $this->request->getRequestTarget());
Blocks/src/Template/Admin/Regions/form.ctp+1 −1 modified@@ -12,7 +12,7 @@ $this->Breadcrumbs->add(__d('croogo', 'Blocks'), [ ]); if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($region->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($region->title), $this->request->getRequestTarget()); } if ($this->request->params['action'] == 'add') {
Contacts/src/Template/Admin/Contacts/form.ctp+1 −1 modified@@ -5,7 +5,7 @@ $this->extend('Croogo/Core./Common/admin_edit'); $this->Breadcrumbs->add(__d('croogo', 'Contacts'), ['controller' => 'contacts', 'action' => 'index']); if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($contact->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($contact->title), $this->request->getRequestTarget()); } if ($this->request->params['action'] == 'add') {
Contacts/src/Template/Admin/Messages/form.ctp+1 −1 modified@@ -8,7 +8,7 @@ $this->Breadcrumbs->add(__d('croogo', 'Contacts'), ['plugin' => 'Croogo/Contacts', 'controller' => 'Messages', 'action' => 'index']); if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($message->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($message->title), $this->request->getRequestTarget()); } $this->append('form-start', $this->Form->create($message));
Contacts/src/Template/Admin/Messages/index.ctp+5 −5 modified@@ -83,14 +83,14 @@ foreach ($messages as $message) { 'class' => 'row-select', 'id' => 'Messages'. $message->id . 'Id', ]), - $message->contact->title, - $message->name, - $message->email, + h($message->contact->title), + h($message->name), + h($message->email), $commentIcon . ' ' . $this->Html->link($message->title, '#', [ 'class' => 'comment-view', 'data-target' => '#comment-modal', - 'data-title' => $message->title, - 'data-content' => $message->body, + 'data-title' => h($message->title), + 'data-content' => h($message->body), ]), $this->Time->i18nFormat($message->created), $actions,
Contacts/src/Template/Admin/Messages/view.ctp+1 −1 modified@@ -5,7 +5,7 @@ $this->extend('Croogo/Core./Common/admin_view'); $this->Breadcrumbs ->add(__d('croogo', 'Messages'), ['action' => 'index']); - $this->Breadcrumbs->add($message->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($message->title), $this->request->getRequestTarget()); $this->append('action-buttons'); echo $this->Croogo->adminAction(__d('croogo', 'List Messages'), ['action' => 'index']);
Core/src/View/Helper/CroogoHelper.php+1 −1 modified@@ -168,7 +168,7 @@ public function adminMenus($menus, $options = [], $depth = 0) $menu['htmlAttributes'] += ['icon' => $menu['icon']]; } if ($sidebar) { - $title .= '<span>' . $menu['title'] . '</span>'; + $title .= '<span>' . h($menu['title']) . '</span>'; } else { $title .= $menu['title']; }
Core/src/View/Helper/CroogoHtmlHelper.php+1 −1 modified@@ -224,7 +224,7 @@ public function status($value, $url = []) */ public function link($title, $url = null, array $options = [], $confirmMessage = false) { - $defaults = ['escape' => false]; + $defaults = ['escape' => true]; $options = is_null($options) ? [] : $options; $options = array_merge($defaults, $options); $iconDefaults = $this->config('iconDefaults');
FileManager/src/Template/Admin/Attachments/browse.ctp+1 −1 modified@@ -22,7 +22,7 @@ $this->Html->script('Croogo/FileManager.attachments/browse', ['block' => true]); 'class' => 'text-muted', ]); - $cardHeader = $this->Html->div('card-header', $attachment->title); + $cardHeader = $this->Html->div('card-header', h($attachment->title)); $cardBlock = $this->Html->div('card-body', $thumbnail); $cardFooter = $this->Html->div('card-footer', $footerText); $card = $this->Html->div('card text-center selector',
FileManager/src/Template/Admin/Attachments/edit.ctp+2 −1 modified@@ -5,7 +5,7 @@ $this->extend('Croogo/Core./Common/admin_edit'); $this->Breadcrumbs->add(__d('croogo', 'Attachments'), ['plugin' => 'Croogo/FileManager', 'controller' => 'attachments', 'action' => 'index']) - ->add($attachment->title, $this->request->getRequestTarget()); + ->add(h($attachment->title), $this->request->getRequestTarget()); $this->append('form-start', $this->Form->create($attachment)); @@ -52,6 +52,7 @@ else: endif; $preview = $this->Html->link($imgUrl, $attachment->path, [ 'data-toggle' => 'lightbox', + 'escape' => false, ]); echo $this->Html->beginBox(__d('croogo', 'Preview')) . $preview; echo $this->Html->endBox();
FileManager/src/Template/Admin/Attachments/index.ctp+1 −1 modified@@ -78,7 +78,7 @@ foreach ($attachments as $attachment) { $this->Form->checkbox('Attachments.' . $attachment->id . '.id', ['class' => 'row-select']), $attachment->id, $thumbnail, - $this->Html->tag('div', $attachment->title, ['class' => 'ellipsis']), + $this->Html->tag('div', h($attachment->title), ['class' => 'ellipsis']), $this->Html->tag('div', $this->Html->link($this->Url->build($attachment->path, true), $attachment->path, ['target' => '_blank']), ['class' => 'ellipsis']),
Menus/src/Template/Admin/Links/form.ctp+2 −2 modified@@ -8,7 +8,7 @@ $this->Croogo->adminScript('Croogo/Menus.admin'); $this->Breadcrumbs->add(__d('croogo', 'Menus'), ['controller' => 'Menus', 'action' => 'index']); if ($this->request->params['action'] == 'add') { - $this->Breadcrumbs->add($menu->title, [ + $this->Breadcrumbs->add(h($menu->title), [ 'action' => 'index', '?' => ['menu_id' => $menu->id], ]) @@ -20,7 +20,7 @@ if ($this->request->params['action'] == 'add') { } if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($menu->title, [ + $this->Breadcrumbs->add(h($menu->title), [ 'action' => 'index', '?' => ['menu_id' => $menu->id], ])
Menus/src/Template/Admin/Links/index.ctp+1 −1 modified@@ -8,7 +8,7 @@ $this->Croogo->adminscript('Croogo/Menus.admin'); $this->extend('Croogo/Core./Common/admin_index'); $this->Breadcrumbs->add(__d('croogo', 'Menus'), ['controller' => 'Menus', 'action' => 'index']) - ->add(__d('croogo', $menu->title), $this->request->getRequestTarget()); + ->add(h(__d('croogo', $menu->title)), $this->request->getRequestTarget()); $this->append('action-buttons'); echo $this->Croogo->adminAction(__d('croogo', 'New link'), ['action' => 'add', 'menu_id' => $menu->id], ['button' => 'success']);
Menus/src/Template/Admin/Menus/form.ctp+1 −1 modified@@ -7,7 +7,7 @@ $this->extend('Croogo/Core./Common/admin_edit'); $this->Breadcrumbs->add(__d('croogo', 'Menus'), ['action' => 'index']); if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($menu->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($menu->title), $this->request->getRequestTarget()); $this->assign('title', __d('croogo', 'Edit Menu')); }
Meta/src/Template/Admin/Meta/form.ctp+1 −1 modified@@ -8,7 +8,7 @@ $this->Breadcrumbs->add(__d('croogo', 'Settings'), ['plugin' => 'Croogo/Settings $this->Breadcrumbs->add(__d('croogo', 'Meta'), ['action' => 'index']); if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($$viewVar->key, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($$viewVar->key), $this->request->getRequestTarget()); $this->assign('title', __d('croogo', 'Edit Meta')); }
Nodes/src/Template/Admin/Nodes/form.ctp+7 −11 modified@@ -13,30 +13,26 @@ if ($this->request->params['action'] == 'add') { $this->assign('title', __d('croogo', 'Create content: %s', $type->title)); $this->Breadcrumbs->add(__d('croogo', 'Create'), ['action' => 'create']) - ->add($type->title, $this->request->getRequestTarget()); + ->add(h($type->title), $this->request->getRequestTarget()); } if ($this->request->params['action'] == 'edit') { - $this->Breadcrumbs->add($node->title, $this->request->getRequestTarget(), [ - 'innerAttrs' => [ - 'title' => $node->title, - ], - ]); + $this->Breadcrumbs->add(h($node->title), $this->request->getRequestTarget()); } $this->append('form-start', $this->Form->create($node, [ 'class' => 'protected-form', ])); $this->start('tab-heading'); - echo $this->Croogo->adminTab(__d('croogo', $type->title), '#node-main'); + echo $this->Croogo->adminTab(__d('croogo', h($type->title)), '#node-main'); $this->end(); $this->start('tab-content'); echo $this->Html->tabStart('node-main'); echo $this->Form->input('title', [ 'label' => false, - 'placeholder' => __d('croogo', '%s title', $type->title), + 'placeholder' => __d('croogo', '%s title', h($type->title)), 'data-slug' => '#slug', 'data-slug-editable' => true, 'data-slug-edit-class' => 'btn btn-secondary btn-sm', @@ -66,7 +62,7 @@ $this->start('panels'); $username = isset($node->user->username) ? $node->user->username : $this->request->session() ->read('Auth.User.username'); echo $this->Html->beginBox(__d('croogo', 'Publishing')); - echo $this->element('Croogo/Core.admin/buttons', ['type' => $type->title]); + echo $this->element('Croogo/Core.admin/buttons', ['type' => h($type->title)]); echo $this->element('Croogo/Core.admin/publishable'); echo $this->Form->input('promote', [ @@ -75,7 +71,7 @@ $this->start('panels'); ]); echo $this->Html->endBox(); - echo $this->Html->beginBox(__d('croogo', '%s attributes', $type->title)); + echo $this->Html->beginBox(__d('croogo', '%s attributes', h($type->title))); echo $this->Form->autocomplete('user_id', [ 'label' => __d('croogo', 'Author'), 'options' => $users, @@ -100,7 +96,7 @@ $this->start('panels'); 'options' => $parents, 'default' => $node->parent_id, 'autocomplete' => [ - 'default' => $node->parent ? $node->parent->title : null, + 'default' => $node->parent ? h($node->parent->title) : null, 'data-displayField' => 'title', 'data-queryField' => 'title', 'data-relatedElement' => '#parent-id',
Nodes/src/Template/Nodes/view.ctp+1 −1 modified@@ -5,7 +5,7 @@ $this->assign('title', $node->title); $this->Nodes->set($node); ?> <div id="node-<?= $this->Nodes->field('id') ?>" class="node node-type-<?= $this->Nodes->field('type') ?>"> - <h2><?= $this->Nodes->field('title') ?></h2> + <h2><?= h($this->Nodes->field('title')) ?></h2> <?php echo $this->Nodes->info(); echo $this->Nodes->body();
Settings/src/Template/Admin/Settings/form.ctp+1 −1 modified@@ -9,7 +9,7 @@ $this->Breadcrumbs ]); if ($this->request->param('action') == 'edit') { - $this->Breadcrumbs->add($setting->key, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($setting->key), $this->request->getRequestTarget()); } if ($this->request->param('action') == 'add') {
Settings/src/Template/Admin/Settings/index.ctp+4 −4 modified@@ -9,9 +9,9 @@ $this->Breadcrumbs 'controller' => 'Settings', 'action' => 'index', )); -if (!empty($this->request->params['named']['p'])) { - $this->Breadcrumbs->add($this->request->params['named']['p']); -} +if ($this->request->getQuery('key')): + $this->Breadcrumbs->add(h($this->request->getQuery('key'))); +endif; $this->start('table-heading'); $tableHeaders = $this->Html->tableHeaders(array( $this->Paginator->sort('id', __d('croogo', 'Id')), @@ -57,7 +57,7 @@ $this->append('table-body'); $rows[] = array( $setting->id, $this->Html->link($keyPrefix, array('controller' => 'Settings', 'action' => 'index', '?' => array('key' => $keyPrefix))) . $keyTitle, - $this->Text->truncate($setting->value, 20), + $this->Text->truncate(h($setting->value), 20), $this->Html->status($setting->editable), $actions, );
Taxonomy/src/Template/Admin/Terms/index.ctp+1 −1 modified@@ -8,7 +8,7 @@ $this->Breadcrumbs->add(__d('croogo', 'Content'), ['plugin' => 'Croogo/Nodes', 'controller' => 'Nodes', 'action' => 'index']) ->add(__d('croogo', 'Vocabularies'), ['plugin' => 'Croogo/Taxonomy', 'controller' => 'Vocabularies', 'action' => 'index']) - ->add($vocabulary->title, $this->request->getRequestTarget()); + ->add(h($vocabulary->title), $this->request->getRequestTarget()); $this->append('action-buttons'); echo $this->Croogo->adminAction(__d('croogo', 'Create term'), [
Taxonomy/src/Template/Admin/Types/form.ctp+1 −1 modified@@ -9,7 +9,7 @@ $this->Breadcrumbs if ($this->request->params['action'] == 'edit') { $this->assign('title', __d('croogo', 'Edit Type')); - $this->Breadcrumbs->add($type->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($type->title), $this->request->getRequestTarget()); } if ($this->request->params['action'] == 'add') {
Users/src/Template/Admin/Roles/form.ctp+1 −1 modified@@ -5,7 +5,7 @@ $this->Breadcrumbs ->add(__d('croogo', 'Roles'), ['plugin' => 'Croogo/Users', 'controller' => 'Roles', 'action' => 'index']); if ($this->request->param('action') == 'edit') { - $this->Breadcrumbs->add($role->title, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($role->title), $this->request->getRequestTarget()); } if ($this->request->param('action') == 'add') {
Users/src/Template/Admin/Users/form.ctp+1 −1 modified@@ -9,7 +9,7 @@ $this->Breadcrumbs->add(__d('croogo', 'Users'), ['plugin' => 'Croogo/Users', 'controller' => 'Users', 'action' => 'index']); if ($this->request->param('action') == 'edit') { - $this->Breadcrumbs->add($user->name, $this->request->getRequestTarget()); + $this->Breadcrumbs->add(h($user->name), $this->request->getRequestTarget()); $this->assign('title', __d('croogo', 'Edit user %s', $user->username)); } else { $this->assign('title', __d('croogo', 'New user'));
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-v6q8-8wgx-8hm7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-7171ghsaADVISORY
- github.com/croogo/croogo/commit/cafaaabe2cef3d1d83652370e30563e6ad7c4158ghsaWEB
- github.com/croogo/croogo/issues/887ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.