Vulnerability: ScratchTools is a web extension designed to make interacting with the Scratch programming language community (Scratching) easier. In affected versions anybody who uses the Recently Viewed Projects feature is vulnerable to having their account taken over if they view a project that tries to. The issue is that if a user visits a project that includes Javascript in the title, then when the Recently Viewed Projects feature displays it, it could run the Javascript. This issue has been addressed in the 2.5.2 release. Users having issues scratching should open an issue in the project issue tracker https://github.com/STForScratch/ScratchTools/
Vulnerability ID: CVE-2022-31094
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/STForScratch/ScratchTools
Published: 2022-06-27
File: features/recently-viewed-projects.js
Commit message: Merge pull request #55 from STForScratch/fix-project-recently-viewed-security-issue

Fix Security Bug with Recently Viewed Projects
Commit author: rgantzos

Vulnerable version (before fix):
 function removeAllChildNodes(parent) {         }     Object.keys(data).forEach(function(project) {         var pr = document.createElement('li')         pr.innerHTML = `<div class="media-item-content not-shared"><div class="media-thumb"><a href="/projects/${data[project]['id']}/"><img src="${data[project]['image']}"></a></div><div class="media-info"><span class="media-info-item title"><a href="/projects/${data[project]['id']}/">${data[project]['title']}</a></span></div></div>`        document.querySelector('ul.media-list').prepend(pr)     })     deleteButton()     function deleteButton() {

Fixed version (after fix):
 function removeAllChildNodes(parent) {         }     Object.keys(data).forEach(function(project) {         var pr = document.createElement('li')         pr.innerHTML = `<div class="media-item-content not-shared"><div class="media-thumb"><a href="/projects/${data[project]['id']}/"><img src="${data[project]['image']}"></a></div><div class="media-info"><span class="media-info-item title"><a href="/projects/${data[project]['id']}/" class="ScratchToolsProjectTitle"></a></span></div></div>`        pr.querySelector('a.ScratchToolsProjectTitle').textContent = data[project]['title']         document.querySelector('ul.media-list').prepend(pr)     })     deleteButton()     function deleteButton() {

Patch:
patch: @@ -79,8 +79,9 @@ function removeAllChildNodes(parent) {
         }
     Object.keys(data).forEach(function(project) {
         var pr = document.createElement('li')
-        pr.innerHTML = `<div class="media-item-content not-shared"><div class="media-thumb"><a href="/projects/${data[project]['id']}/"><img src="${data[project]['image']}"></a></div><div class="media-info"><span class="media-info-item title"><a href="/projects/${data[project]['id']}/">${data[project]['title']}</a></span></div></div>`
-       document.querySelector('ul.media-list').prepend(pr)
+        pr.innerHTML = `<div class="media-item-content not-shared"><div class="media-thumb"><a href="/projects/${data[project]['id']}/"><img src="${data[project]['image']}"></a></div><div class="media-info"><span class="media-info-item title"><a href="/projects/${data[project]['id']}/" class="ScratchToolsProjectTitle"></a></span></div></div>`
+       pr.querySelector('a.ScratchToolsProjectTitle').textContent = data[project]['title']
+        document.querySelector('ul.media-list').prepend(pr)
     })
     deleteButton()
     function deleteButton() {
path: features/recently-viewed-projects.js