In-depth guide
HTML entities, escaping and markup security
HTML character references, numeric references, contextual escaping, sanitization and their relationship to XSS prevention.
Why character references exist
HTML reserves some characters for markup syntax. Character references represent characters when a literal form would be ambiguous, inconvenient or unavailable, using names such as & or numeric references.
Modern HTML handles Unicode directly, so not every non-ASCII character needs an entity. References are mainly useful for syntax-sensitive characters and conventional representations.
Named and numeric references
Named character references map standardized names to characters or sequences; numeric references identify a Unicode code point in decimal or hexadecimal form. The HTML parser resolves both into resulting text.
A numeric reference identifies a Unicode code point, not the UTF-8 bytes used to transport the document. File encoding and entity syntax are separate layers.
Escaping is context-dependent
HTML text, attribute values, URLs, CSS and embedded JavaScript have different grammars. Correct escaping must know the output context: a replacement suitable for a text node can be insufficient or incorrect inside a script.
Secure template engines therefore apply contextual escaping. Disabling auto-escaping or manually concatenating markup with untrusted data increases the chance that data becomes executable syntax.
Escaping versus sanitization
Escaping keeps data as text inside a specific context. Sanitization accepts potentially active markup and removes or restricts elements, attributes and URLs according to a policy.
If users are allowed to submit a subset of HTML, replacing angle brackets is not enough. Use a maintained HTML sanitizer that operates on parsed structure.
XSS and trust boundaries
Cross-site scripting occurs when attacker-controlled data reaches an executable browser context. Prevention combines contextual output encoding, sanitization where HTML is accepted and APIs that avoid dangerous sinks.
Entities are not a universal security filter: data can be safe in one text context and dangerous after decoding or reinsertion elsewhere. Follow the full data flow.
Best practices
Keep UTF-8 end-to-end, rely on framework escaping where possible and avoid repeated encode/decode cycles without a clear contract. Test quotes, ampersands, syntax characters and Unicode at boundaries.
When the goal is plain text, use APIs that create text nodes. When markup is required, define an allowlist and use mature sanitization libraries rather than regular expressions or ad-hoc substitutions.