CVE-2020-15274: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: In Wiki.js before version 2.5.162, an XSS payload can be injected in a page title and executed via the search results. While the title is properly escaped in both the navigation links and the actual page title, it is not the case in the search results. Commit a57d9af34c15adbf460dde6553d964efddf433de fixes this vulnerability (version 2.5.162) by properly escaping the text content displayed in the search results.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2020-10-26T19:15Z
Repository: https://github.com/Requarks/wiki
Language: Other
Files changed: client/components/common/search-results.vue
Commit date: 2020-10-23 18:49:25 -0400
Commit message: Merge pull request from GHSA-pgjv-84m7-62q7


Diff: diff --git a/client/components/common/search-results.vue b/client/components/common/search-results.vue
index da46975ba..b96e59890 100644
--- a/client/components/common/search-results.vue
+++ b/client/components/common/search-results.vue
@@ -20,13 +20,13 @@
           template(v-for='(item, idx) of results')
             v-list-item(@click='goToPage(item)', :key='item.id', :class='idx === cursor ? `highlighted` : ``')
               v-list-item-avatar(tile)
                 img(src='/_assets/svg/icon-selective-highlighting.svg')
               v-list-item-content
-                v-list-item-title(v-html='item.title')
-                v-list-item-subtitle.caption(v-html='item.description')
-                .caption.grey--text(v-html='item.path')
+                v-list-item-title(v-text='item.title')
+                v-list-item-subtitle.caption(v-text='item.description')
+                .caption.grey--text(v-text='item.path')
               v-list-item-action
                 v-chip(label, outlined) {{item.locale.toUpperCase()}}
             v-divider(v-if='idx < results.length - 1')
         v-pagination.mt-3(
           v-if='paginationLength > 1'
@@ -41,11 +41,11 @@
           template(v-for='(term, idx) of suggestions')
             v-list-item(:key='term', @click='setSearchTerm(term)', :class='idx + results.length === cursor ? `highlighted` : ``')
               v-list-item-avatar
                 v-icon mdi-magnify
               v-list-item-content
-                v-list-item-title(v-html='term')
+                v-list-item-title(v-text='term')
             v-divider(v-if='idx < suggestions.length - 1')
       .text-xs-center.pt-5(v-if='search && search.length > 1')
         //- v-btn.mx-2(outlined, color='orange', @click='search = ``', v-if='results.length > 0')
         //-   v-icon(left) mdi-content-save
         //-   span {{$t('common:header.searchCopyLink')}}

Vulnerable code:                 v-list-item-title(v-html='item.title')
                v-list-item-subtitle.caption(v-html='item.description')
                .caption.grey--text(v-html='item.path')
                v-list-item-title(v-html='term')
Fixed code:                 v-list-item-title(v-text='item.title')
                v-list-item-subtitle.caption(v-text='item.description')
                .caption.grey--text(v-text='item.path')
                v-list-item-title(v-text='term')