diff options
author | Phil Hughes <me@iamphill.com> | 2017-09-25 13:33:45 +0000 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2017-10-15 21:48:01 -0700 |
commit | c7b8e61d8db9eca4abb8a2b2fcac0eababa28a09 (patch) | |
tree | a375c39edd7cd5358182089a4923aa195b54f7cf | |
parent | 7358c69f26a32eb6ba606fe77cb138368aa3474d (diff) | |
download | gitlab-ce-c7b8e61d8db9eca4abb8a2b2fcac0eababa28a09.tar.gz |
Merge branch 'winh-search-bar-xss' into 'security-10-0'
Escape user name in filtered search bar
See merge request gitlab/gitlabhq!2194
-rw-r--r-- | app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js | 4 | ||||
-rw-r--r-- | spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js | 23 |
2 files changed, 25 insertions, 2 deletions
diff --git a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js index 28e8240169d..55c153a6d46 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js +++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js @@ -123,8 +123,8 @@ class FilteredSearchVisualTokens { /* eslint-disable no-param-reassign */ tokenValueContainer.dataset.originalValue = tokenValue; tokenValueElement.innerHTML = ` - <img class="avatar s20" src="${user.avatar_url}" alt="${user.name}'s avatar"> - ${user.name} + <img class="avatar s20" src="${user.avatar_url}" alt=""> + ${_.escape(user.name)} `; /* eslint-enable no-param-reassign */ }) diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js index 67166802c70..2ecb64d84b5 100644 --- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js @@ -791,6 +791,29 @@ describe('Filtered Search Visual Tokens', () => { expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); const avatar = tokenValueElement.querySelector('img.avatar'); expect(avatar.src).toBe(dummyUser.avatar_url); + expect(avatar.alt).toBe(''); + }) + .then(done) + .catch(done.fail); + }); + + it('escapes user name when creating token', (done) => { + const dummyUser = { + name: '<script>', + avatar_url: `${gl.TEST_HOST}/mypics/avatar.png`, + }; + const { tokenValueContainer, tokenValueElement } = findElements(authorToken); + const tokenValue = tokenValueElement.innerText; + usersCacheSpy = (username) => { + expect(`@${username}`).toBe(tokenValue); + return Promise.resolve(dummyUser); + }; + + subject.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) + .then(() => { + expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); + tokenValueElement.querySelector('.avatar').remove(); + expect(tokenValueElement.innerHTML.trim()).toBe(_.escape(dummyUser.name)); }) .then(done) .catch(done.fail); |