Escape Special Characters
ID |
html.spec_char_escape |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Html |
Tags |
reliability |
Description
Flags text content that contains a raw < or a raw & that does not begin a character reference.
Rationale
In HTML text content the characters < and & have a structural meaning: a raw < starts a tag
and a raw & starts a character reference. Leaving them unescaped is a parse risk — depending on
what follows, the browser may swallow part of the text, misread it as markup, or recover in a way
that differs from the author’s intent.
<p>a < b</p> <!-- FLAW — raw < -->
<p>Tom & Jerry</p> <!-- FLAW — bare & -->
<p>a & b</p> <!-- OK — escaped & -->
<p>x < y</p> <!-- OK — escaped < -->
The rule only looks at HTML text content. The bodies of <script> and <style> are raw text: the
browser hands them verbatim to the JavaScript / CSS engine without decoding entities, so escaping
there would corrupt the code. Template expressions ({{ … }}) are engine code, not HTML text.
Neither is reported.
<script>
$("#name").after("<span class='ok'></span>"); <!-- OK — raw text, must stay unescaped -->
</script>
<style>
.card &:hover { color: blue } <!-- OK — CSS nesting -->
</style>
<p>{{ a < b && c }}</p> <!-- OK — template expression -->
A template statement is stepped over instead. The control-flow blocks of a component template
(@if, @for, @switch, @defer, @let, and the {% … %} tags of the Jinja family) are
written among the markup, so a single run of text carries both the block header — where && is an
operator and < a comparison — and the prose around it, where an & really does need escaping.
Only the header is masked, so the text inside the block is still checked.
@if (screen == 'deletePolicy' && screen != 'file') { <!-- OK — condition, not text -->
<p>Tom & Jerry</p> <!-- FLAW — prose inside the block -->
}
Remediation
Write the special characters as character references: < for < and & for &. A > may
be left as-is, but > is also acceptable.