XSS and Injection Risks in LWC
By the end of this lesson, you'll be able to:
- Explain how LWC template bindings auto-escape data by default
- Identify the specific ways XSS risk can be reintroduced despite that default
- Prefer template bindings over innerHTML for rendering dynamic content
Prerequisites: "Lightning Web Security"
Auto-Escaping by Default
<p>{userComment}</p>
If userComment contains <script>alert('xss')</script>, this renders as harmless literal text on the page, not as executable script — LWC's {expression} template bindings automatically HTML-escape their content. Simply displaying user-supplied text through a template binding is safe by default, a real, meaningful difference from naive string concatenation into raw HTML.
Where Risk Can Be Reintroduced
// Unsafe — bypasses the framework's auto-escaping entirely
this.template.querySelector('div.comment').innerHTML = userComment;
<!-- Also risky — opts this element out of LWC's usual management -->
<div lwc:dom="manual"></div>
Directly setting innerHTML from JavaScript bypasses the framework's escaping completely — if userComment contains a script tag, it executes. lwc:dom="manual" similarly hands control of an element's contents back to the developer, removing the framework's default protection for whatever gets placed there.
The Safe Alternative
<!-- Safe -->
<div class="comment">{userComment}</div>
The fix for the unsafe example above is almost always simply this — bind the value directly in the template instead of manually assigning innerHTML. Reaching for innerHTML to display plain dynamic text is rarely actually necessary.
Why This Matters in Real Projects
Even with Lightning Web Security (Lesson 3) reducing the platform's overall attack surface, a developer can still reintroduce a classic XSS vulnerability by deliberately choosing innerHTML or lwc:dom="manual" over ordinary template bindings — the framework's defaults are safe, but they can be opted out of.
Exercise
Rewrite this unsafe innerHTML assignment to instead use a safe template binding, given a userName property.
Show hint
Bind the value directly in the template instead.
Exercise
Challenge: explain, as a comment, why {expression} bindings are safe by default but innerHTML assignments are not.
Show hint
Think about what each mechanism does with the string content.
XSS and Injection Risks in LWC Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
LWC template bindings auto-escape data by default, making simple display of user-supplied text safe out of the box — but innerHTML and lwc:dom="manual" can still reintroduce classic XSS if used carelessly.