Moderate severityNVD Advisory· Published Sep 20, 2022· Updated May 29, 2025
Cross-site Scripting (XSS) - Stored in yetiforcecompany/yetiforcecrm
CVE-2022-2924
Description
Cross-site Scripting (XSS) - Stored in GitHub repository yetiforcecompany/yetiforcecrm prior to 6.3.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
yetiforce/yetiforce-crmPackagist | <= 6.4.0 | — |
Affected products
1- Range: unspecified
Patches
1b716ecea3407Improved data display on some widgets
16 files changed · +30 −30
config/version.php+2 −2 modified@@ -1,7 +1,7 @@ <?php return [ - 'appVersion' => '6.4.0', - 'patchVersion' => '2022.08.19', + 'appVersion' => '6.4.1', + 'patchVersion' => '2022.08.22', 'lib_roundcube' => '0.3.0', ];
layouts/basic/modules/Vtiger/dashboards/CalendarActivitiesContents.tpl+3 −3 modified@@ -17,7 +17,7 @@ </style> <div> {foreach from=$ACTIVITIES key=INDEX item=ACTIVITY} - <div class="changeActivity u-cursor-pointer" data-url="{$ACTIVITY->getActivityStateModalUrl()}" accesskey=""> + <div class="changeActivity u-cursor-pointer" data-url="{$ACTIVITY->getActivityStateModalUrl()|escape}" accesskey=""> <div class="rowActivities"> <div class="d-flex mb-1"> <div class=""> @@ -47,7 +47,7 @@ <div class="w-100 mx-1"> {\App\TextUtils::textTruncate($ACTIVITY->getDisplayName(), $NAMELENGTH)} {if $CONTRACTOR} - <br /><small class="small-a">{\App\Language::translate('LBL_FOR')} <strong>{$ACTIVITY->getDisplayValue('contractor')}</strong></small>, <strong><small class='small-a'><a href="{$CONTRACTOR->getDetailViewUrl()}">{\App\TextUtils::textTruncate($CONTRACTOR->getDisplayName(), $HREFNAMELENGTH)}</a></small></strong> + <br /><small class="small-a">{\App\Language::translate('LBL_FOR')} <strong>{$ACTIVITY->getDisplayValue('contractor')}</strong></small>, <strong><small class='small-a'><a href="{$CONTRACTOR->getDetailViewUrl()|escape}">{\App\TextUtils::textTruncate($CONTRACTOR->getDisplayName(), $HREFNAMELENGTH)}</a></small></strong> {/if} {if $LINK} <br /><small class="small-a">{\App\Language::translate('LBL_FOR')} <strong>{$ACTIVITY->getDisplayValue('link')}</strong></small> @@ -84,7 +84,7 @@ {/foreach} {if $PAGING_MODEL->get('nextPageExists') eq 'true'} <div class="float-right padding5"> - <button type="button" class="btn btn-sm btn-primary showMoreHistory" data-url="{$WIDGET->getUrl()}&page={$PAGING_MODEL->getNextPage()}"> + <button type="button" class="btn btn-sm btn-primary showMoreHistory" data-url="{$WIDGET->getUrl()|escape}&page={$PAGING_MODEL->getNextPage()}"> {\App\Language::translate('LBL_MORE')} </button> </div>
layouts/basic/modules/Vtiger/dashboards/CalendarContents.tpl+2 −2 modified@@ -1,8 +1,8 @@ {*<!-- {[The file is published on the basis of YetiForce Public License 5.0 that can be found in the following directory: licenses/LicenseEN.txt or yetiforce.com]} -->*} {strip} <input type="hidden" id="currentView" value="{$VIEW}" /> - <input type="hidden" id="activity_view" value="{$CURRENT_USER->getDetail('activity_view')}" /> - <input type="hidden" id="date_format" value="{$CURRENT_USER->getDetail('date_format')}" /> + <input type="hidden" id="activity_view" value="{$CURRENT_USER->getDetail('activity_view')|escape}" /> + <input type="hidden" id="date_format" value="{$CURRENT_USER->getDetail('date_format')|escape}" /> <input type="hidden" id="defaultDate" value="{$DEFAULTDATE}" /> <div class="js-calendar__container" data-js="fullcalendar"></div> {/strip}
layouts/basic/modules/Vtiger/dashboards/Calendar.tpl+1 −1 modified@@ -60,7 +60,7 @@ </label> </div> <input type="hidden" value="current" data-current="{implode('##',$CURRENT_STATUS)}" - data-history="{implode(',',$HISTORY_STATUS)}" class="widgetFilterSwitch" {if !empty($WIDGET_DATA['defaultFilter'])} data-default-filter="{$WIDGET_DATA['defaultFilter']}" {/if}> + data-history="{implode(',',$HISTORY_STATUS)|escape}" class="widgetFilterSwitch" {if !empty($WIDGET_DATA['defaultFilter'])} data-default-filter="{$WIDGET_DATA['defaultFilter']|escape}" {/if}> {/if} </div> <div class="col-ceq-xsm-6">
layouts/basic/modules/Vtiger/dashboards/ChartFilterContents.tpl+1 −1 modified@@ -42,7 +42,7 @@ {if $IS_SUMMARY} {$SUMMARY[$HEADER][] = $CHART_DATA.$HEADER.$GROUP_HEADER.$VALUE_TYPE} {/if} {assign var=VALUE value=$CHART_MODEL->convertToUserFormat($CHART_DATA.$HEADER.$GROUP_HEADER.$VALUE_TYPE)} {if !empty($CHART_DATA.$HEADER.$GROUP_HEADER.link)} - <a href="{$CHART_DATA.$HEADER.$GROUP_HEADER.link}">{$VALUE}</a> + <a href="{$CHART_DATA.$HEADER.$GROUP_HEADER.link|escape}">{$VALUE}</a> {else} {$VALUE} {/if}
layouts/basic/modules/Vtiger/dashboards/ChartFilter.tpl+2 −2 modified@@ -15,7 +15,7 @@ <div> <div class="form-group row mb-2"> <label class="{$COL_LBL}">{\App\Language::translate('LBL_WIDGET_NAME','Home')}</label> - <div class="{$COL_CTRL}"><input type="text" class="form-control" name="title" value="{$WIDGET_MODEL->getValueForEditView('title')}"></div> + <div class="{$COL_CTRL}"><input type="text" class="form-control" name="title" value="{\App\Purifier::encodeHtml($WIDGET_MODEL->getValueForEditView('title'))}"></div> </div> <div class="form-group row mb-2"> <label class="{$COL_LBL}"><span class="redColor">*</span>{\App\Language::translate('LBL_SELECT_CHART','Home')}</label> @@ -59,7 +59,7 @@ <div class="{$COL_CTRL}"> {assign "VALUE_FILTER" $WIDGET_MODEL->getValueForEditView('filterid')} <select class="form-control filtersId" {if $CHART_TYPE!=='Funnel' && $CHART_TYPE!=='Table' }name="filtersId" - multiple="multiple" {else}name="filtersId[]" + multiple="multiple" {else}name="filtersId[]" {/if} data-validation-engine="validate[required]" data-maximum-selection-length="{\App\Config::performance('CHART_MULTI_FILTER_LIMIT')}"> <option></option>
layouts/basic/modules/Vtiger/dashboards/DashBoardContents.tpl+2 −2 modified@@ -44,8 +44,8 @@ data-js="css-element-queries"> <div id="{$WIDGETDOMID}" {if $smarty.foreach.count.index % $COLUMNS == 0 and $smarty.foreach.count.index != 0} {/if} class="grid-stack-item-content dashboardWidget dashboardWidget_{$smarty.foreach.count.index}" - data-url="{$WIDGET->getUrl()}" - data-mode="open" data-name="{$WIDGET->getName()}" data-cache="{$WIDGET->get('cache')}" + data-url="{$WIDGET->getUrl()|escape}" + data-mode="open" data-name="{\App\Purifier::encodeHtml($WIDGET->getName())}" data-cache="{$WIDGET->get('cache')|escape}" data-loader="widgetLoader"> </div> </div>
layouts/basic/modules/Vtiger/dashboards/DashboardHeaderIcons.tpl+2 −2 modified@@ -16,11 +16,11 @@ </a> {/if} - <button class="btn btn-sm btn-light js-widget-refresh" title="{\App\Language::translate('LBL_REFRESH')}" data-url="{$WIDGET->getUrl()}&content=data" data-js="click"> + <button class="btn btn-sm btn-light js-widget-refresh" title="{\App\Language::translate('LBL_REFRESH')}" data-url="{$WIDGET->getUrl()|escape}&content=data" data-js="click"> <span class="fas fa-sync-alt"></span> </button> {if !$WIDGET->isDefault()} - <button class="btn btn-sm btn-light js-widget-remove" title="{\App\Language::translate('LBL_CLOSE')}" data-url="{$WIDGET->getDeleteUrl()}" data-js="click"> + <button class="btn btn-sm btn-light js-widget-remove" title="{\App\Language::translate('LBL_CLOSE')}" data-url="{$WIDGET->getDeleteUrl()|escape}" data-js="click"> <span class="fas fa-times"></span> </button> {/if}
layouts/basic/modules/Vtiger/dashboards/DashBoardPreProcessAjax.tpl+2 −2 modified@@ -16,11 +16,11 @@ {assign var=COUNT value=count($MODULES_WITH_WIDGET)} <ul class="nav nav-inverted-tabs massEditTabs selectDashboradView ml-sm-2"> {foreach from=$MODULES_WITH_WIDGET item=MODULE_WIDGET} - <li class="nav-item" data-module="{$MODULE_WIDGET}"> + <li class="nav-item" data-module="{$MODULE_WIDGET|escape}"> <a class="nav-link pt-1 pb-1 {if $MODULE_NAME eq $MODULE_WIDGET} active {/if}{if $COUNT === 1} d-none{/if}" href="#" data-toggle="tab"> - <span class="yfm-{$MODULE_WIDGET} mx-1"></span> + <span class="yfm-{$MODULE_WIDGET|escape} mx-1"></span> {\App\Language::translate($MODULE_WIDGET, $MODULE_WIDGET)} </a> </li>
layouts/basic/modules/Vtiger/dashboards/DashBoardWidgetsList.tpl+2 −2 modified@@ -12,8 +12,8 @@ <div class="js-widget-list dropdown-menu widgetsList addWidgetDropDown" data-js="container"> {assign var="WIDGET" value=""} {foreach from=$WIDGETS item=WIDGET} - <a class="js-widget-list__item dropdown-item d-flex" href="#" data-name="{$WIDGET->getName()}" data-id="{$WIDGET->get('widgetid')}" - data-widget-url="{$WIDGET->getUrl()}" data-linkid="{$WIDGET->get('linkid')}" + <a class="js-widget-list__item dropdown-item d-flex" href="#" data-name="{\App\Purifier::encodeHtml($WIDGET->getName())}" data-id="{$WIDGET->get('widgetid')}" + data-widget-url="{$WIDGET->getUrl()|escape}" data-linkid="{$WIDGET->get('linkid')}" data-width="{$WIDGET->getWidth()}" data-height="{$WIDGET->getHeight()}" data-js="remove | click"> {\App\Language::translate($WIDGET->getTitle(), $MODULE_NAME, null, true, 'Dashboard')} {if $WIDGET->isDeletable()}
layouts/basic/modules/Vtiger/dashboards/ListUpdatedRecordContents.tpl+1 −1 modified@@ -22,7 +22,7 @@ {foreach key=$index item=record from=$LIST} <tr> {foreach from=$record item=item key=key} - <td>{$item}</td> + <td>{\App\Purifier::encodeHtml($item)}</td> {/foreach} </tr> {/foreach}
layouts/basic/modules/Vtiger/dashboards/MailsList.tpl+3 −3 modified@@ -10,11 +10,11 @@ <div class="d-flex flex-row flex-nowrap no-gutters justify-content-between"> {include file=\App\Layout::getTemplatePath('dashboards/WidgetHeaderTitle.tpl', $MODULE_NAME)} <div class="d-inline-flex"> - <button class="btn btn-sm btn-light js-widget-refresh" title="{\App\Language::translate('LBL_REFRESH')}" data-url="{$WIDGET->getUrl()}&content=data" data-js="click"> + <button class="btn btn-sm btn-light js-widget-refresh" title="{\App\Language::translate('LBL_REFRESH')}" data-url="{$WIDGET->getUrl()|escape}&content=data" data-js="click"> <span class="fas fa-sync-alt"></span> </button> {if !$WIDGET->isDefault()} - <button class="btn btn-sm btn-light js-widget-remove" title="{\App\Language::translate('LBL_CLOSE')}" data-url="{$WIDGET->getDeleteUrl()}" data-js="click"> + <button class="btn btn-sm btn-light js-widget-remove" title="{\App\Language::translate('LBL_CLOSE')}" data-url="{$WIDGET->getDeleteUrl()|escape}" data-js="click"> <span class="fas fa-times"></span> </button> {/if} @@ -34,7 +34,7 @@ <option value="-">{\App\Language::translate('--None--', $MODULE_NAME)}</option> {else} {foreach from=$ACCOUNTSLIST item=item key=key} - <option title="{$item['username']}" value="{$item['user_id']}" {if $USER == $item['user_id']}selected{/if}>{$item['username']}</option> + <option title="{\App\Purifier::encodeHtml($item['username'])}" value="{$item['user_id']}" {if $USER == $item['user_id']}selected{/if}>{\App\Purifier::encodeHtml($item['username'])}</option> {/foreach} {/if} </select>
layouts/basic/modules/Vtiger/dashboards/MiniListWizard.tpl+3 −3 modified@@ -34,7 +34,7 @@ <td class="fieldLabel alignMiddle textAlignCenter" nowrap>{App\Language::translate('LBL_WIDGET_NAME','Home')}</td> <td class="fieldValue position-relative"> - <input type="text" class="form-control" name="widgetTitle" value="{$WIDGET_MODEL->getValueForEditView('title')}" + <input type="text" class="form-control" name="widgetTitle" value="{\App\Purifier::encodeHtml($WIDGET_MODEL->getValueForEditView('title'))}" data-validation-engine="validate[required]" {if $WIDGET_ID} disabled{/if}> </td> </tr> @@ -46,7 +46,7 @@ <select class="form-control select2" name="module" {if $WIDGET_ID} disabled{/if}> <option></option> {foreach from=$MODULES item=MODULE_MODEL key=MODULE_THIS_NAME} - <option value="{$MODULE_MODEL['name']}" {if $MODULE_MODEL['name'] === $VALUE_FIELD} selected{/if}>{App\Language::translate($MODULE_MODEL['name'], $MODULE_MODEL['name'])}</option> + <option value="{$MODULE_MODEL['name']|escape}" {if $MODULE_MODEL['name'] === $VALUE_FIELD} selected{/if}>{App\Language::translate($MODULE_MODEL['name'], $MODULE_MODEL['name'])}</option> {/foreach} </select> </td> @@ -152,7 +152,7 @@ <select class="form-control" name="fields" size="2" multiple="true"> <option></option> {foreach from=$LIST_VIEW_FIELDS item=FIELD key=FIELD_NAME} - <option value="{$FIELD_NAME}">{\App\Language::translate($FIELD->getFieldLabel(),$SELECTED_MODULE)}</option> + <option value="{$FIELD_NAME|escape}">{\App\Language::translate($FIELD->getFieldLabel(),$SELECTED_MODULE)}</option> {/foreach} </select> <select class="form-control" name="filter_fields">
layouts/basic/modules/Vtiger/dashboards/ProductsSoldToRenewContents.tpl+1 −1 modified@@ -28,7 +28,7 @@ {/foreach} {if count($WIDGET_RECORDS) >= $WIDGET_MODEL->getRecordLimit()} <button class="btn btn-light float-right btn-sm goToListView" - data-url="{$WIDGET_MODEL->getUrl()}" + data-url="{$WIDGET_MODEL->getUrl()|escape}" title="{\App\Language::translate('LBL_MORE', $MODULE_NAME)}"> <span>{\App\Language::translate('LBL_MORE', $MODULE_NAME)}</span> </button>
layouts/basic/modules/Vtiger/dashboards/ProductsSoldToRenew.tpl+1 −1 modified@@ -33,7 +33,7 @@ <div class="col-ceq-xsm-6"> <div class="float-right"> <button class="btn btn-light btn-sm ml-1 goToListView" - data-url="{$WIDGET_MODEL->getUrl()}" + data-url="{$WIDGET_MODEL->getUrl()|escape}" title="{\App\Language::translate('LBL_GO_TO_RECORDS_LIST', $MODULE_NAME)}"> <span class="fas fa-th-list"></span> </button>
layouts/basic/modules/Vtiger/dashboards/SelectAccessibleTemplate.tpl+2 −2 modified@@ -38,11 +38,11 @@ {if in_array('users', $ACCESS_OPTIONS['available'])} {assign var=AJAX_URL value=$AJAX_URL|cat:"&result[]=users"} {/if} - data-ajax-search="1" data-ajax-url="{$AJAX_URL}" data-minimum-input="{App\Config::performance('OWNER_MINIMUM_INPUT_LENGTH')}" + data-ajax-search="1" data-ajax-url="{$AJAX_URL|escape}" data-minimum-input="{App\Config::performance('OWNER_MINIMUM_INPUT_LENGTH')}" {/if}> {if in_array('mine', $ACCESS_OPTIONS.available)} - <option value="{$USER_MODEL->getId()}" data-name="{$USER_MODEL->getName()}" + <option value="{$USER_MODEL->getId()}" data-name="{$USER_MODEL->getName()|escape}" title="{\App\Language::translate('LBL_MINE')}" {if $OWNER eq $USER_MODEL->getId()} selected {/if}>{\App\Language::translate('LBL_MINE')}</option> {/if} {if in_array('all', $ACCESS_OPTIONS.available)}
Vulnerability mechanics
Generated by null/stub 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-2qf8-h7pr-x2r8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-2924ghsaADVISORY
- github.com/yetiforcecompany/yetiforcecrm/commit/b716ecea340783b842498425faa029800bd30420ghsax_refsource_MISCWEB
- huntr.dev/bounties/f0f3aded-6e97-4cf2-980a-c90f2c6ca0e0ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.