Skip to content

fix(translate): prevent XSS via translation API response#692

Merged
maboloshi merged 1 commit into
maboloshi:gh-pagesfrom
sebastiondev:fix/cwe79-main-greasyfork-user-xss-8f90
May 17, 2026
Merged

fix(translate): prevent XSS via translation API response#692
maboloshi merged 1 commit into
maboloshi:gh-pagesfrom
sebastiondev:fix/cwe79-main-greasyfork-user-xss-8f90

Conversation

@sebastiondev
Copy link
Copy Markdown
Contributor

Summary

The translation feature in main(greasyfork).user.js and main_zh-TW.user.js inserts text returned by a third-party translation API (iflyrec.com) directly into the GitHub page DOM using insertAdjacentHTML. Because the API response is interpolated into an HTML string without sanitization, a compromised or man-in-the-middle'd API response containing <script> tags or event handlers would execute arbitrary JavaScript in the user's GitHub session.

This is a DOM-based Cross-Site Scripting vulnerability (CWE-79).

Affected code

Both files construct a translation result string like:

const translatedHTML = `<span>...</span><br/>${translatedText}`;
element.insertAdjacentHTML('afterend', translatedHTML);

translatedText comes directly from the HTTP response of https://www.iflyrec.com / https://fanyi.iflyrec.com and is never sanitized before being inserted as HTML.

Exploitation scenario

An attacker who can control or tamper with the translation API response (e.g., via API compromise, DNS hijack, or a rogue CDN edge) can inject arbitrary HTML/JS. When a user clicks the "Translate" button on any GitHub issue, PR, or README, the malicious payload executes in the context of github.com — with access to the user's session cookies, CSRF tokens, and full GitHub API access.

PoC — simulated malicious API response:

If the translation API returns:

<img src=x onerror="alert(document.cookie)">

…then clicking "Translate" on any translatable element injects that <img> tag into the page, triggering the onerror handler and executing JavaScript in the user's GitHub session.

To reproduce locally: intercept the API response (e.g., using a browser extension or proxy like mitmproxy) and replace the translated text field with the payload above. Click the translate button — the alert fires.

Fix

This PR separates the trusted static HTML (the attribution label/link) from the untrusted dynamic text (the API response). The static markup is set via innerHTML on a newly created container element, while the API response text is appended using document.createTextNode(), which treats its input as plain text and never parses HTML. The container is then inserted using element.after().

This preserves the existing visual layout and functionality while ensuring that no content from the translation API can be interpreted as HTML or script.

Testing

  • Verified that normal translation text renders correctly as plain text after the fix.
  • Verified that a malicious payload like <img src=x onerror=alert(1)> is rendered as visible escaped text rather than being parsed as HTML.
  • Confirmed no changes to the static attribution markup or link behavior.

Adversarial review

Before submitting, we considered whether this is actually exploitable: the userscript runs with @grant none, so it operates in the page's JS context directly — there is no Greasemonkey sandbox isolating it. The translation API is accessed over HTTPS, which mitigates casual MITM, but does not protect against API-side compromise, supply-chain attacks on the API provider, or scenarios where the API intentionally returns HTML (e.g., formatting tags that happen to include event handlers). Given that this userscript executes on github.com where session tokens are high-value targets, treating the API response as trusted HTML is an unnecessary risk that this fix eliminates.


Submitted by Sebastion — autonomous open-source security research from Foundation Machines. Free for public repos via the Sebastion AI GitHub App.

@maboloshi maboloshi merged commit e64a48e into maboloshi:gh-pages May 17, 2026
@sebastiondev
Copy link
Copy Markdown
Contributor Author

Appreciate the review.

P.S. More of these run autonomously out of Foundation Machines if you would like coverage on other repos.

maboloshi added a commit that referenced this pull request May 17, 2026
- 重构:抽离 CONFIG/State,引入 safe() 错误边界包裹关键函数,函数拆分细化,processMutations 祖先去重
- 新增:暗色主题适配 (GM_addStyle)、未命中词条管理器、开发者模式、onurlchange 支持
- 修复:#686、XSS 漏洞 (#692)、TreeWalker 空选择器报错、翻译按钮重复添加、shadowRoot 空值崩溃、页面切换后 State.pageConfig 未清空
- 性能:减少无效 DOM 遍历
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants