diff options
Diffstat (limited to 'spec/frontend/users_select/index_spec.js')
-rw-r--r-- | spec/frontend/users_select/index_spec.js | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/spec/frontend/users_select/index_spec.js b/spec/frontend/users_select/index_spec.js index 0d2aae78944..3757e63c4f9 100644 --- a/spec/frontend/users_select/index_spec.js +++ b/spec/frontend/users_select/index_spec.js @@ -108,4 +108,39 @@ describe('~/users_select/index', () => { }); }); }); + + describe('XSS', () => { + const escaped = '><script>alert(1)</script>'; + const issuableType = 'merge_request'; + const user = { + availability: 'not_set', + can_merge: true, + name: 'name', + }; + const selected = true; + const username = 'username'; + const img = '<img user-avatar />'; + const elsClassName = 'elsclass'; + + it.each` + prop | val | element + ${'username'} | ${'><script>alert(1)</script>'} | ${'.dropdown-menu-user-username'} + ${'name'} | ${'><script>alert(1)</script>'} | ${'.dropdown-menu-user-full-name'} + `('properly escapes the $prop $val', ({ prop, val, element }) => { + const u = prop === 'username' ? val : username; + const n = prop === 'name' ? val : user.name; + const row = UsersSelect.prototype.renderRow( + issuableType, + { ...user, name: n }, + selected, + u, + img, + elsClassName, + ); + const fragment = document.createRange().createContextualFragment(row); + const output = fragment.querySelector(element).innerHTML.trim(); + + expect(output).toBe(escaped); + }); + }); }); |