From 76ae8322855197b621756315e67d44c322801ab6 Mon Sep 17 00:00:00 2001 From: boomzero Date: Thu, 19 Feb 2026 16:27:43 +0800 Subject: [PATCH 1/8] Fix XSS vulnerability in post title rendering Sanitize post title with escapeHTML() before inserting into innerHTML to prevent script injection via crafted post titles. Co-Authored-By: Claude Opus 4.6 --- XMOJ.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index aba3fd3d..24ba886a 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -5202,7 +5202,7 @@ int main() Delete.style.display = ""; } } - PostTitle.innerHTML = ResponseData.Data.Title + (ResponseData.Data.ProblemID == 0 ? "" : ` - 题目` + ` ` + ResponseData.Data.ProblemID + ``); + PostTitle.innerHTML = escapeHTML(ResponseData.Data.Title) + (ResponseData.Data.ProblemID == 0 ? "" : ` - 题目` + ` ` + ResponseData.Data.ProblemID + ``); document.title = "讨论" + ThreadID + ": " + ResponseData.Data.Title; PostAuthor.innerHTML = ""; GetUsernameHTML(PostAuthor.children[0], ResponseData.Data.UserID); From eba35cdd8505cb988e3327c67260705c7cede75a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 08:28:53 +0000 Subject: [PATCH 2/8] 3.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f59d6be..62b60c53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmoj-script", - "version": "3.1.0", + "version": "3.1.1", "description": "an improvement script for xmoj.tech", "main": "AddonScript.js", "scripts": { From bc07e5763e541574de738d6e72fef03548e0bcc9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 08:28:59 +0000 Subject: [PATCH 3/8] Update version info to 3.1.1 --- Update.json | 11 +++++++++++ XMOJ.user.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Update.json b/Update.json index fbf81e36..cc93908a 100644 --- a/Update.json +++ b/Update.json @@ -3348,6 +3348,17 @@ } ], "Notes": "v3 显然需要在新年第一天发布(" + }, + "3.1.1": { + "UpdateDate": 1771489733913, + "Prerelease": true, + "UpdateContents": [ + { + "PR": 910, + "Description": "Fix XSS in post title rendering" + } + ], + "Notes": "Fixed a stored XSS vulnerability in discussion thread post titles." } } } \ No newline at end of file diff --git a/XMOJ.user.js b/XMOJ.user.js index 24ba886a..0b120687 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name XMOJ -// @version 3.1.0 +// @version 3.1.1 // @description XMOJ增强脚本 // @author @XMOJ-Script-dev, @langningchen and the community // @namespace https://github/langningchen From ececcfad735c821a12e0fb807a7fa7aff9db2bf0 Mon Sep 17 00:00:00 2001 From: boomzero Date: Thu, 19 Feb 2026 17:24:42 +0800 Subject: [PATCH 4/8] Fix additional XSS vulnerabilities in innerHTML assignments Sanitize user-controlled data with escapeHTML() before innerHTML insertion: - Post titles in thread list - Board name in thread view - EditPerson username in reply edit info - UserID and UserNick on profile page - Update description in changelog Co-Authored-By: Claude Opus 4.6 --- XMOJ.user.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index 0b120687..826d210a 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1912,7 +1912,7 @@ async function main() { let UpdateDataCardListItem = document.createElement("li"); UpdateDataCardList.appendChild(UpdateDataCardListItem); UpdateDataCardListItem.className = "list-group-item"; - UpdateDataCardListItem.innerHTML = "(" + "#" + Data.UpdateContents[j].PR + ") " + Data.UpdateContents[j].Description; + UpdateDataCardListItem.innerHTML = "(" + "#" + Data.UpdateContents[j].PR + ") " + escapeHTML(Data.UpdateContents[j].Description); } let UpdateDataCardLink = document.createElement("a"); UpdateDataCardBody.appendChild(UpdateDataCardLink); @@ -3418,7 +3418,7 @@ async function main() { let UpdateDataCardListItem = document.createElement("li"); UpdateDataCardList.appendChild(UpdateDataCardListItem); UpdateDataCardListItem.className = "list-group-item"; - UpdateDataCardListItem.innerHTML = "(" + "#" + Data.UpdateContents[j].PR + ") " + Data.UpdateContents[j].Description; + UpdateDataCardListItem.innerHTML = "(" + "#" + Data.UpdateContents[j].PR + ") " + escapeHTML(Data.UpdateContents[j].Description); } let UpdateDataCardLink = document.createElement("a"); UpdateDataCardBody.appendChild(UpdateDataCardLink); @@ -3709,8 +3709,8 @@ async function main() { let UserInfoElement = document.createElement("div"); UserInfoElement.classList.add("col-auto"); UserInfoElement.style.lineHeight = "40px"; - UserInfoElement.innerHTML += "用户名:" + UserID + "
"; - UserInfoElement.innerHTML += "昵称:" + UserNick + "
"; + UserInfoElement.innerHTML += "用户名:" + escapeHTML(UserID) + "
"; + UserInfoElement.innerHTML += "昵称:" + escapeHTML(UserNick) + "
"; if (UtilityEnabled("Rating")) { UserInfoElement.innerHTML += "评分:" + ((await GetUserInfo(UserID)).Rating) + "
"; } @@ -4858,7 +4858,7 @@ int main() TitleLink.classList.add("link-secondary"); TitleLink.innerHTML = "🔒 "; } - TitleLink.innerHTML += Posts[i].Title; + TitleLink.innerHTML += escapeHTML(Posts[i].Title); let AuthorCell = document.createElement("td"); Row.appendChild(AuthorCell); GetUsernameHTML(AuthorCell, Posts[i].UserID); @@ -5207,7 +5207,7 @@ int main() PostAuthor.innerHTML = ""; GetUsernameHTML(PostAuthor.children[0], ResponseData.Data.UserID); PostTime.innerHTML = GetRelativeTime(ResponseData.Data.PostTime); - PostBoard.innerHTML = ResponseData.Data.BoardName; + PostBoard.innerHTML = escapeHTML(ResponseData.Data.BoardName); let Replies = ResponseData.Data.Reply; PostReplies.innerHTML = ""; for (let i = 0; i < Replies.length; i++) { @@ -5357,7 +5357,7 @@ int main() if (Replies[i].EditPerson == Replies[i].UserID) { ReplyContentElement.innerHTML += `最后编辑于${GetRelativeTime(Replies[i].EditTime)}`; } else { - ReplyContentElement.innerHTML += `最后被${Replies[i].EditPerson}编辑于${GetRelativeTime(Replies[i].EditTime)}`; + ReplyContentElement.innerHTML += `最后被${escapeHTML(Replies[i].EditPerson)}编辑于${GetRelativeTime(Replies[i].EditTime)}`; } } let ContentEditElement = document.createElement("div"); From 9f41a7191640ae078b5c9483146f5ae18a80a6b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 09:25:26 +0000 Subject: [PATCH 5/8] 3.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62b60c53..7c668d9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmoj-script", - "version": "3.1.1", + "version": "3.1.2", "description": "an improvement script for xmoj.tech", "main": "AddonScript.js", "scripts": { From e51cb29a63b677a89691dc7a34fde2267f682828 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 09:25:32 +0000 Subject: [PATCH 6/8] Update version info to 3.1.2 --- Update.json | 11 +++++++++++ XMOJ.user.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Update.json b/Update.json index cc93908a..baa8c19d 100644 --- a/Update.json +++ b/Update.json @@ -3359,6 +3359,17 @@ } ], "Notes": "Fixed a stored XSS vulnerability in discussion thread post titles." + }, + "3.1.2": { + "UpdateDate": 1771493127347, + "Prerelease": true, + "UpdateContents": [ + { + "PR": 911, + "Description": "Fix additional XSS vulnerabilities" + } + ], + "Notes": "Fixed additional stored XSS vulnerabilities where user-controlled data was inserted into innerHTML without sanitization." } } } \ No newline at end of file diff --git a/XMOJ.user.js b/XMOJ.user.js index 826d210a..592d8ffc 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name XMOJ -// @version 3.1.1 +// @version 3.1.2 // @description XMOJ增强脚本 // @author @XMOJ-Script-dev, @langningchen and the community // @namespace https://github/langningchen From 015b3ea8ebd150c5b91dd0828b1deef3392cbece Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 09:28:40 +0000 Subject: [PATCH 7/8] 3.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c668d9a..9dd923ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmoj-script", - "version": "3.1.2", + "version": "3.2.0", "description": "an improvement script for xmoj.tech", "main": "AddonScript.js", "scripts": { From e155083bc5c64d56c24c78fedb014c2c0b315204 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 19 Feb 2026 09:28:41 +0000 Subject: [PATCH 8/8] Update to release 3.2.0 --- Update.json | 15 +++++++++++++++ XMOJ.user.js | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Update.json b/Update.json index baa8c19d..467e4c56 100644 --- a/Update.json +++ b/Update.json @@ -3370,6 +3370,21 @@ } ], "Notes": "Fixed additional stored XSS vulnerabilities where user-controlled data was inserted into innerHTML without sanitization." + }, + "3.2.0": { + "UpdateDate": 1771493320789, + "Prerelease": false, + "UpdateContents": [ + { + "PR": 910, + "Description": "Fix XSS in post title rendering" + }, + { + "PR": 911, + "Description": "Fix additional XSS vulnerabilities" + } + ], + "Notes": "No release notes were provided for this release." } } } \ No newline at end of file diff --git a/XMOJ.user.js b/XMOJ.user.js index 592d8ffc..74e4ef53 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name XMOJ -// @version 3.1.2 +// @version 3.2.0 // @description XMOJ增强脚本 // @author @XMOJ-Script-dev, @langningchen and the community // @namespace https://github/langningchen