VYPR
Moderate severityNVD Advisory· Published Aug 6, 2021· Updated Aug 4, 2024

CVE-2020-22330

CVE-2020-22330

Description

Cross-Site Scripting (XSS) vulnerability in Subrion 4.2.1 via the title when adding a page.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Subrion 4.2.1 is vulnerable to stored XSS via the page title field when adding a new page, allowing arbitrary script execution.

Vulnerability

CVE-2020-22330 is a stored Cross-Site Scripting (XSS) vulnerability in Subrion CMS version 4.2.1. The flaw exists in the page title field when adding a new page; the application fails to sanitize user input before rendering it in the menu and other administrative interfaces. The vulnerable code path is reachable by any authenticated user with permission to create or edit pages. The official fix, visible in commits [1] and [3], adds the |escape Smarty modifier to template expressions such as {$menu.text|escape} and {$page.title|escape} to properly HTML-escape output. The vulnerability was reported in GitHub issue #850 [2].

Exploitation

An attacker with a valid account and the ability to create or edit pages (e.g., an editor or administrator) can craft a malicious payload, such as ``, and inject it into the page title field. When the vulnerable page is saved, the payload is stored in the database. The malicious script then executes in the browsers of any user who views a page that displays the title, such as the navigation menu or the pages management panel. No additional user interaction beyond viewing the affected interface is required for the stored payload to fire.

Impact

Successful exploitation of this stored XSS vulnerability allows the attacker to execute arbitrary JavaScript in the context of the victim's session. This can lead to session hijacking, defacement, credential theft, or redirection to malicious sites. The impact is limited to the privileges of the victim user; however, if an administrator views the injected page, the attacker could gain full administrative control over the CMS instance.

Mitigation

The vulnerability was patched by the vendor in the Subrion repository on an unspecified date; the fix is included in commits 0e9180d [1] and 06950c2 [3]. Upgrading to a version of Subrion that incorporates these commits (likely 4.2.2 or later) or applying the patches manually eliminates the XSS vector. As of the publication date (2021-08-06), no known workaround was documented; users who cannot upgrade should ensure that only trusted users have page creation privileges and consider using a web application firewall to filter malicious input.

AI Insight generated on May 21, 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.

PackageAffected versionsPatched versions
intelliants/subrionPackagist
>= 4.2.1, < 4.2.24.2.2

Affected products

2

Patches

2
0e9180d2330a

#850 additional escaping in menu ul

https://github.com/intelliants/subrionDaiyrbek ArtelovFeb 27, 2020via ghsa
4 files changed · +9 9
  • templates/_common/menu-ul.tpl+2 2 modified
    @@ -7,7 +7,7 @@
                     {if 'mainmenu' == $position && $menu@iteration > $core.config.max_top_menu_items|default:5 && $menu.level < 1}{capture append=dropdown name=$menu.page_name}{/if}
     
                     {if in_array($position, ['left', 'right', 'user1', 'user2', 'top'])}
    -                    <a class="list-group-item{if $menu.active} active{/if}" href="{if $menu.url}{$menu.url}{else}{$smarty.const.IA_SELF}#{/if}"{if $menu.nofollow} rel="nofollow"{/if}{if $menu.new_window} target="_blank"{/if}>{$menu.text}</a>
    +                    <a class="list-group-item{if $menu.active} active{/if}" href="{if $menu.url}{$menu.url}{else}{$smarty.const.IA_SELF}#{/if}"{if $menu.nofollow} rel="nofollow"{/if}{if $menu.new_window} target="_blank"{/if}>{$menu.text|escape}</a>
                     {else}
                         <li class="m_{$menu.page_name}
                             {if isset($data[$menu.el_id]) || isset($menu_children)} dropdown{/if}
    @@ -20,7 +20,7 @@
                                     {if $menu.nofollow} rel="nofollow"{/if}
                                     {if $menu.new_window} target="_blank"{/if}
                             >
    -                            {$menu.text}
    +                            {$menu.text|escape}
                             </a>
                             {if (isset($data[$menu.el_id]) || isset($menu_children)) && $menu.level == 0  && $position != 'left'}<span class="navbar-nav__drop dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="fa fa-angle-down"></span></span>{/if}
                             {if isset($data[$menu.el_id])}
    
  • templates/_common/render-menu.tpl+4 4 modified
    @@ -7,9 +7,9 @@
             <ul class="nav navbar-nav navbar-right nav-account">
                 <li class="dropdown">
                     <a href="#" class="dropdown-toggle" data-toggle="dropdown">
    -                    {ia_image file=$member.avatar title=$member.fullname|default:$member.username class='img-circle' gravatar=true email=$member.email}
    +                    {ia_image file=$member.avatar title=$member.fullname|escape|default:$member.username|escape class='img-circle' gravatar=true email=$member.email}
     
    -                    {$member.fullname|default:$member.username}
    +                    {$member.fullname|escape|default:$member.username|escape}
                     </a>
                     <span class="navbar-nav__drop dropdown-toggle" data-toggle="dropdown"><span class="fa fa-angle-down"></span></span>
                     {ia_hooker name='smartyFrontInsideAccountBox'}
    @@ -24,7 +24,7 @@
         {/if}
     {elseif in_array($position, ['left', 'right', 'user1', 'user2', 'top'])}
         {if !empty($menu.contents[0]) && 'account' != $menu.name}
    -        {ia_block header=$menu.header title=$menu.title movable=true id=$menu.id name=$menu.name collapsible=$menu.collapsible classname=$menu.classname}
    +        {ia_block header=$menu.header title=$menu.title|escape movable=true id=$menu.id name=$menu.name collapsible=$menu.collapsible classname=$menu.classname}
                 {ia_menu menus=$menu.contents class="list-group {$menu.classname}"}
             {/ia_block}
         {/if}
    @@ -33,7 +33,7 @@
     {else}
         <!--__ms_{$menu.id}-->
         {if $menu.header || isset($manageMode)}
    -        <div class="nav-menu-header {$menu.classname}">{$menu.title}</div>
    +        <div class="nav-menu-header {$menu.classname}">{$menu.title|escape}</div>
         {else}
             <div class="menu {$menu.classname}">
         {/if}
    
  • templates/kickstart/menu-ul.tpl+2 2 modified
    @@ -7,7 +7,7 @@
                     {if 'mainmenu' == $position && $menu@iteration > $core.config.max_top_menu_items|default:5 && $menu.level < 1}{capture append=dropdown name=$menu.page_name}{/if}
     
                     {if in_array($position, array('left', 'right', 'user1', 'user2', 'top'))}
    -                    <a class="list-group-item{if $menu.active} active{/if}" href="{if $menu.url}{$menu.url}{else}{$smarty.const.IA_SELF}#{/if}"{if $menu.nofollow} rel="nofollow"{/if}{if $menu.new_window} target="_blank"{/if}>{$menu.text}</a>
    +                    <a class="list-group-item{if $menu.active} active{/if}" href="{if $menu.url}{$menu.url}{else}{$smarty.const.IA_SELF}#{/if}"{if $menu.nofollow} rel="nofollow"{/if}{if $menu.new_window} target="_blank"{/if}>{$menu.text|escape}</a>
                     {else}
                         <li class="m_{$menu.page_name}
                             {if isset($data[$menu.el_id]) || isset($menu_children)} dropdown{/if}
    @@ -21,7 +21,7 @@
                                 {if $menu.new_window} target="_blank"{/if}
                                 {if (isset($data[$menu.el_id]) || isset($menu_children)) && $menu.level == 0  && $position != 'left'}data-toggle="dropdown"{/if}
                             >
    -                            {$menu.text}
    +                            {$menu.text|escape}
                                 {if (isset($data[$menu.el_id]) || isset($menu_children)) && $menu.level == 0  && $position != 'left'}<span class="caret"></span>{/if}
                             </a>
                             {if isset($data[$menu.el_id])}
    
  • templates/kickstart/render-menu.tpl+1 1 modified
    @@ -26,7 +26,7 @@
         {/if}
     {elseif in_array($position, array('left', 'right', 'user1', 'user2', 'top'))}
         {if !empty($menu.contents[0]) && 'account' != $menu.name}
    -        {ia_block header=$menu.header title=$menu.title movable=true id=$menu.id name=$menu.name collapsible=$menu.collapsible classname=$menu.classname}
    +        {ia_block header=$menu.header title=$menu.title|escape movable=true id=$menu.id name=$menu.name collapsible=$menu.collapsible classname=$menu.classname}
                 {ia_menu menus=$menu.contents class="list-group {$menu.classname}"}
             {/ia_block}
         {/if}
    
06950c2f9c4a

Resolves #850

https://github.com/intelliants/subrionDaiyrbek ArtelovFeb 26, 2020via ghsa
1 file changed · +3 3
  • admin/templates/default/blocks.tpl+3 3 modified
    @@ -96,7 +96,7 @@
                     <div class="col col-lg-8">
                         <ul class="nav nav-tabs">
                             {foreach $pagesGroup as $group => $row}
    -                            <li{if $row@iteration == 1} class="active"{/if}><a href="#tab-visible_{$row.name}" data-toggle="tab">{$row.title}</a></li>
    +                            <li{if $row@iteration == 1} class="active"{/if}><a href="#tab-visible_{$row.name}" data-toggle="tab">{$row.title|escape}</a></li>
                             {/foreach}
                         </ul>
     
    @@ -148,7 +148,7 @@
     
                         <ul class="nav nav-tabs">
                             {foreach $pagesGroup as $group => $row}
    -                            <li{if $row@iteration == 1} class="active"{/if}><a href="#tab-pages_{$row.name}" data-toggle="tab">{$row.title}</a></li>
    +                            <li{if $row@iteration == 1} class="active"{/if}><a href="#tab-pages_{$row.name}" data-toggle="tab">{$row.title|escape}</a></li>
                             {/foreach}
                         </ul>
     
    @@ -168,7 +168,7 @@
                                         <div class="checkbox">
                                             <label>
                                                 <input type="checkbox" name="pages[]" class="{$classname}" value="{$page.name}"{if in_array($page.name, $menuPages, true)} checked{/if}>
    -                                            {if empty($page.title)}{$page.name}{else}{$page.title}{/if}
    +                                            {if empty($page.title)}{$page.name|escape}{else}{$page.title|escape}{/if}
                                             </label>
                                         </div>
                                         {/if}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.