🛡️ Sentinel: [MEDIUM] Fix HTML injection risk in QTextEdit - #224
Conversation
In PyQt6 applications, `QTextEdit` widgets accept rich text (HTML) by default. If untrusted log output, generated model text, or pasted user input contains HTML tags, the widget will heuristically parse and render them. This introduces a risk of HTML injection or UI redressing, allowing attackers to maliciously format text, inject links, or break the intended display layout. This commit explicitly sets `.setAcceptRichText(False)` on all `QTextEdit` instances (`setup_dialog.py`, `hub_dialog.py`, `chat_panel.py`, and `settings_panel.py`) to prevent HTML injection via pasted prompts or programmatic insertions if `insertPlainText()` is not strictly used. A new entry was also added to `.jules/sentinel.md` detailing this learning. Co-authored-by: dieterolson <198168927+dieterolson@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 837fc7d10e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| **Vulnerability:** In PyQt6 applications, `QTextEdit` widgets accept rich text (HTML) by default. If untrusted log output, generated model text, or pasted user input contains HTML tags, the widget will render them. This introduces a risk of HTML injection or UI redressing, allowing attackers to maliciously format text, inject links, or break the intended display layout. | ||
| **Learning:** Even if `QTextEdit` is set to read-only or intended for plain text configuration (like a system prompt), it will heuristically parse pasted or programmatically inserted text as HTML unless explicitly instructed otherwise. | ||
| **Prevention:** Always apply `.setAcceptRichText(False)` to `QTextEdit` instances to enforce plain text input and display, unless rich text editing is explicitly required by the feature. |
There was a problem hiding this comment.
Correct the unsafe QTextEdit prevention guidance
When future code inserts untrusted output through append(), setText(), or setHtml(), setAcceptRichText(False) will not protect it because that property only restricts user-originated rich-text insertion such as paste and drag-and-drop. This new prevention rule could therefore reintroduce the exact vulnerability it claims to avoid; retain setAcceptRichText(False) for editable fields, but document insertPlainText() as required for programmatic output.
AGENTS.md reference: AGENTS.md:L25-L26
Useful? React with 👍 / 👎.
In PyQt6 applications, `QTextEdit` widgets accept rich text (HTML) by default. If untrusted log output, generated model text, or pasted user input contains HTML tags, the widget will heuristically parse and render them. This introduces a risk of HTML injection or UI redressing, allowing attackers to maliciously format text, inject links, or break the intended display layout. This commit explicitly sets `.setAcceptRichText(False)` on all `QTextEdit` instances (`setup_dialog.py`, `hub_dialog.py`, `chat_panel.py`, and `settings_panel.py`) to prevent HTML injection via pasted prompts or programmatic insertions if `insertPlainText()` is not strictly used. SPEC.md was also updated to reflect the new security enhancement. Co-authored-by: dieterolson <198168927+dieterolson@users.noreply.github.com>
Severity: MEDIUM
Vulnerability: In PyQt6,
QTextEditwidgets evaluate and render rich text (HTML) by default. This makes the application vulnerable to HTML injection if user input (e.g., pasted into the system prompt configuration) or programmatically appended outputs (if.append()were used) contained HTML-like content.Impact: A user could paste malicious HTML into the configuration, or if logs/AI text generated HTML, it would render inside the desktop client leading to UI redressing or deceptive formatting.
Fix: Explicitly disabled rich text acceptance by calling
.setAcceptRichText(False)on theQTextEditinstances across the application (Setup Dialog, Hub Dialog, Chat Panel, Settings Panel).Verification: Run
uv run pytest tests/unit/to ensure no functionality is broken. Manually verify by attempting to paste HTML into the system promptQTextEditwhich will now only accept and render raw text.PR created automatically by Jules for task 10787830303746246525 started by @dieterolson