CVE-2019-7168
Description
Croogo through v3.0.5 contains a stored-self XSS vulnerability in the Blog field, allowing authenticated attackers to inject arbitrary HTML/JS.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Croogo through v3.0.5 contains a stored-self XSS vulnerability in the Blog field, allowing authenticated attackers to inject arbitrary HTML/JS.
Vulnerability
A stored-self cross-site scripting (XSS) vulnerability exists in Croogo through version 3.0.5, specifically in the Blog field when adding a new blog post via /admin/nodes/nodes/add/blog. The application fails to sanitize user input before storing it, allowing injection of arbitrary HTML or JavaScript code [1][2].
Exploitation
An attacker must be authenticated to the administrative panel. By crafting a malicious payload in the Blog field, the attacker can inject script code that is stored on the server. The injected script executes when any user views the stored content, including the attacker themselves (self-XSS) [2].
Impact
Successful exploitation allows the attacker to execute arbitrary HTML and JavaScript in the context of the victim's browser, potentially leading to session hijacking, data theft, or other malicious actions within the admin interface [1].
Mitigation
The vulnerability is addressed in commit cafaaabe [4], which applies output escaping using the h() function. Users should upgrade to a patched version after 3.0.5. No official workaround is documented; however, custom sanitization of the Blog field input can be implemented as an interim measure.
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-9f9r-w3xq-f722ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-7168ghsaADVISORY
- github.com/croogo/croogo/commit/cafaaabe2cef3d1d83652370e30563e6ad7c4158ghsaWEB
- github.com/croogo/croogo/issues/886ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.