HTML Injection vulnerability in check-code pages using dangerouslySetInnerHTML #15837

Closed
opened 2026-02-21 19:23:35 -05:00 by yindo · 3 comments
Owner

Originally created by @lyzno1 on GitHub (Aug 1, 2025).

Originally assigned to: @douxc on GitHub.

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

main

Cloud or Self Hosted

Cloud

Steps to reproduce

  1. Navigate to any check-code page with malicious email parameter:
    http://localhost:3000/signin/check-code?email=test@example.com<script>alert('XSS')</script>
    
  2. Observe the page rendering behavior

Expected Behavior

The email address should be displayed as plain text with HTML tags visible as literal characters:

We send a verification code to test@example.com<script>alert('XSS')</script>

✔️ Expected Behavior

The email address should be displayed as plain text with HTML tags visible as literal characters:

We send a verification code to test@example.com<script>alert('XSS')</script>

Actual Behavior

Code-level vulnerability exists: The application uses dangerouslySetInnerHTML with unvalidated user input from URL parameters:

<span dangerouslySetInnerHTML={{ __html: t('login.checkCode.tips', { email }) as string }}></span>

Where email comes directly from:

const email = decodeURIComponent(searchParams.get('email') as string)
Originally created by @lyzno1 on GitHub (Aug 1, 2025). Originally assigned to: @douxc on GitHub. ### Self Checks - [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542). - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report, otherwise it will be closed. - [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version main ### Cloud or Self Hosted Cloud ### Steps to reproduce 1. Navigate to any check-code page with malicious email parameter: ``` http://localhost:3000/signin/check-code?email=test@example.com<script>alert('XSS')</script> ``` 2. Observe the page rendering behavior ## Expected Behavior The email address should be displayed as plain text with HTML tags visible as literal characters: ``` We send a verification code to test@example.com<script>alert('XSS')</script> ``` ### ✔️ Expected Behavior The email address should be displayed as plain text with HTML tags visible as literal characters: ``` We send a verification code to test@example.com<script>alert('XSS')</script> ``` ### ❌ Actual Behavior **Code-level vulnerability exists**: The application uses `dangerouslySetInnerHTML` with unvalidated user input from URL parameters: ```tsx <span dangerouslySetInnerHTML={{ __html: t('login.checkCode.tips', { email }) as string }}></span> ``` Where `email` comes directly from: ```tsx const email = decodeURIComponent(searchParams.get('email') as string) ```
yindo added the 🐞 bug label 2026-02-21 19:23:35 -05:00
yindo closed this issue 2026-02-21 19:23:35 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 1, 2025):

This is a confirmed XSS vulnerability: the check-code pages use dangerouslySetInnerHTML to render a translation string with the email parameter directly from the URL, without any sanitization or escaping. This allows attackers to inject arbitrary HTML or JavaScript via the email query parameter, which will be executed in the browser context (console check-code page, webapp-signin check-code page, reset-password check-code page).

To fix this, avoid passing user input to dangerouslySetInnerHTML. Instead, render the email as a plain text node, or escape the email value before interpolation. For example, split the translation string so only the static HTML is rendered with dangerouslySetInnerHTML, and insert the email as a child node, or use a library like he to escape HTML entities in the email before rendering. This will prevent any injected HTML or scripts from being executed.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Aug 1, 2025): <!-- Answer --> This is a confirmed XSS vulnerability: the check-code pages use `dangerouslySetInnerHTML` to render a translation string with the `email` parameter directly from the URL, without any sanitization or escaping. This allows attackers to inject arbitrary HTML or JavaScript via the `email` query parameter, which will be executed in the browser context ([console check-code page](https://github.com/langgenius/dify/blob/bc18d4d1b9a3b2ed5c819ec4c64da91551189626/web/app/signin/check-code/page.tsx), [webapp-signin check-code page](https://github.com/langgenius/dify/blob/bc18d4d1b9a3b2ed5c819ec4c64da91551189626/web/app/(shareLayout)/webapp-signin/check-code/page.tsx), [reset-password check-code page](https://github.com/langgenius/dify/blob/bc18d4d1b9a3b2ed5c819ec4c64da91551189626/web/app/(shareLayout)/webapp-reset-password/check-code/page.tsx)). To fix this, avoid passing user input to `dangerouslySetInnerHTML`. Instead, render the email as a plain text node, or escape the email value before interpolation. For example, split the translation string so only the static HTML is rendered with `dangerouslySetInnerHTML`, and insert the email as a child node, or use a library like `he` to escape HTML entities in the email before rendering. This will prevent any injected HTML or scripts from being executed. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/92c46504-8bc4-4165-9568-53dfada8f5f0?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/6088a4f4-073a-43f3-b3d4-4f06fb0c05a0/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/23294)
Author
Owner

@lyzno1 commented on GitHub (Aug 2, 2025):

Hi @crazywoola, I noticed that the related issue was assigned to someone else after I opened this PR.

Just wanted to check — is there anything in the PR that needs to be improved, or is this the kind of issue that’s typically handled by core maintainers?

Happy to revise or assist in any way. Thanks!

@lyzno1 commented on GitHub (Aug 2, 2025): Hi @crazywoola, I noticed that the related issue was assigned to someone else after I opened this PR. Just wanted to check — is there anything in the PR that needs to be improved, or is this the kind of issue that’s typically handled by core maintainers? Happy to revise or assist in any way. Thanks!
Author
Owner

@crazywoola commented on GitHub (Aug 2, 2025):

Hi @crazywoola, I noticed that the related issue was assigned to someone else after I opened this PR.

Just wanted to check — is there anything in the PR that needs to be improved, or is this the kind of issue that’s typically handled by core maintainers?

Happy to revise or assist in any way. Thanks!

@douxc is our team member, this one needs to be reviewed by him.

@crazywoola commented on GitHub (Aug 2, 2025): > Hi [@crazywoola](https://github.com/crazywoola), I noticed that the related issue was assigned to someone else after I opened this PR. > > Just wanted to check — is there anything in the PR that needs to be improved, or is this the kind of issue that’s typically handled by core maintainers? > > Happy to revise or assist in any way. Thanks! @douxc is our team member, this one needs to be reviewed by him.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#15837