Fix XSS in FormHandler.js showMessages method#36
Fix XSS in FormHandler.js showMessages method#36SteveKinzey wants to merge 1 commit intoWPManageNinja:masterfrom
Conversation
DOM text from heading and message values was being inserted directly into HTML without escaping, allowing potential cross-site scripting. Fixes WPManageNinja#35 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
PR author is not in the allowed authors list. |
📝 WalkthroughWalkthroughA security fix was implemented in FormHandler.js to prevent cross-site scripting (XSS) vulnerabilities. A new Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/public/FormHandler.js (1)
170-193:⚠️ Potential issue | 🟡 MinorPotential XSS in
recordCouponMessage– consider addressing in a follow-up.While this PR correctly fixes XSS in
showMessages, therecordCouponMessagemethod at line 193 appendsmessagedirectly to the DOM without escaping. Themessageparameter can contain user-controlled content likecoupon.code(line 152).Consider applying the same
escapeHtmltreatment here for comprehensive XSS protection.🛡️ Suggested fix for recordCouponMessage
- $responseDiv.append(errorHtml.append(cross, message)); + $responseDiv.append(errorHtml.append(cross, this.escapeHtml(message)));Note: Line 152's template literal would also need escaping:
- let message = `${coupon.code} <span>-${couponAmount}</span>`; + let message = `${this.escapeHtml(coupon.code)} <span>-${couponAmount}</span>`;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/public/FormHandler.js` around lines 170 - 193, The recordCouponMessage function appends unescaped message content into the DOM, allowing XSS; like showMessages, call the existing escapeHtml utility on message before inserting (and on any coupon.code template usage in the recordCouponMessage context) and append the escaped string instead of raw message; ensure the click handler still references this.appliedCoupons and updates .__wpf_all_applied_coupons and calculatePayments unchanged.
🧹 Nitpick comments (1)
src/public/FormHandler.js (1)
739-743: Effective XSS mitigation using the DOM text-node pattern.This is a well-established technique for escaping HTML metacharacters. One minor robustness improvement: guard against non-string inputs to avoid unexpected coercion (e.g.,
null→"null").🛡️ Optional: Add defensive type coercion
escapeHtml(str) { + if (str == null) return ''; const div = document.createElement('div'); - div.appendChild(document.createTextNode(str)); + div.appendChild(document.createTextNode(String(str))); return div.innerHTML; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/public/FormHandler.js` around lines 739 - 743, The escapeHtml function should guard against non-string inputs to avoid unintended coercion; update escapeHtml to first handle null/undefined by returning an empty string, then ensure the value passed to document.createTextNode is an explicit string (e.g., coerce other primitives using String(x)), and keep using the DOM text-node pattern (escapeHtml) with document.createTextNode and div.innerHTML to produce the escaped result.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/public/FormHandler.js`:
- Around line 170-193: The recordCouponMessage function appends unescaped
message content into the DOM, allowing XSS; like showMessages, call the existing
escapeHtml utility on message before inserting (and on any coupon.code template
usage in the recordCouponMessage context) and append the escaped string instead
of raw message; ensure the click handler still references this.appliedCoupons
and updates .__wpf_all_applied_coupons and calculatePayments unchanged.
---
Nitpick comments:
In `@src/public/FormHandler.js`:
- Around line 739-743: The escapeHtml function should guard against non-string
inputs to avoid unintended coercion; update escapeHtml to first handle
null/undefined by returning an empty string, then ensure the value passed to
document.createTextNode is an explicit string (e.g., coerce other primitives
using String(x)), and keep using the DOM text-node pattern (escapeHtml) with
document.createTextNode and div.innerHTML to produce the escaped result.
Summary
escapeHtml()method to safely escape HTML metacharactersheading,message(string), andmessage(object iteration) values before inserting into DOM inshowMessages()Details
src/public/FormHandler.jsinsertsheadingandmessagevalues directly into HTML without escaping. If these contain HTML metacharacters (e.g.<script>tags), they are interpreted as HTML — a DOM-based XSS vulnerability.Identified by GitHub CodeQL (rule: DOM text reinterpreted as HTML, severity: high).
Fixes #35
🤖 Generated with Claude Code