Security Policy and Threat Model
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The entities library is a pure-JavaScript implementation designed for encoding and decoding HTML and XML character entities. Its primary security purpose is to ensure that untrusted string inputs are transformed into safe, predictable string outputs without introducing vulnerabilities into the consuming application. The library operates within a limited scope: it performs no I/O, spawns no subprocesses, and has no runtime dependencies, which inherently reduces its attack surface.
Sources: SECURITY.md:14-17, readme.md:4-15
The project strictly follows the WHATWG HTML named character reference specification. While the library is not an HTML sanitizer, it is a critical component in the data processing pipeline for libraries like htmlparser2 and cheerio. Security considerations focus on preventing Denial of Service (DoS), mitigating downstream Cross-Site Scripting (XSS) through correct decoding, and ensuring that encoding logic prevents context breakouts in HTML/XML environments.
Sources: SECURITY.md:27-38, readme.md:6-10
Threat Model Overview
The threat model for entities identifies four primary areas of security interest. These categories reflect the library's role as a high-performance string processor handling untrusted data.
| Threat Category | Description | Mitigation Focus |
|---|---|---|
| Denial of Service (DoS) | Crafted input causing excessive CPU or memory usage. | Avoiding quadratic behavior and runaway allocations in trie traversal. |
| Downstream XSS | Incorrect decoding that misrepresents input to sanitizers. | Strict adherence to WHATWG spec to prevent smuggled markup. |
| Incorrect Encoding | Failure to escape characters that break out of HTML/XML context. | Proper escaping of special characters like <, >, &, ", and '. |
| Supply Chain | Compromised artifacts or build pipelines. | Secure release processes and Tidelift/GitHub vulnerability reporting. |
Sources: SECURITY.md:19-25, SECURITY.md:27-33
Out of Scope Considerations
The library explicitly excludes vulnerabilities resulting from improper use of its output without context-aware sanitization. It also treats WHATWG spec-conformant quirks as non-security issues, even if the behavior is surprising to developers.
Sources: SECURITY.md:35-40
Architecture and Data Flow
The security of the library is rooted in its use of a Radix Tree (trie) mapped to a Uint16Array for efficient and safe decoding. This structure prevents the overhead of large object allocations and ensures linear-time processing of input strings.
The diagram shows the data flow from untrusted input through specialized processing paths (Trie for decoding, Bitsets/Regex for encoding) to generate safe output.
Sources: scripts/trie/README.md:1-15, src/decode.ts:446-455, src/escape.ts:60-70
Decoding Security Logic
The EntityDecoder and decodeWithTrie functions implement logic to handle various DecodingMode settings. This is crucial for security because "Legacy" mode allows entities without semicolons, which could be exploited if not handled strictly according to the spec in sensitive contexts.
- Numeric Entity Validation: Hex and decimal entities are validated to ensure they contain digits. Code points exceeding
0x10FFFFare automatically mapped to the replacement characterU+FFFDto prevent invalid Unicode smuggling. - Attribute Mode Logic: In
DecodingMode.Attribute, the decoder implements specific termination checks (e.g., characters like=,a-z,0-9following a legacy entity) to prevent misinterpretation of entities within HTML attributes.
Sources: src/decode.ts:167-195, src/decode.ts:251-265, src/decode.ts:606-613
Secure Encoding Implementation
The encoding system uses a combination of bitsets and optimized regular expressions to identify characters that require escaping.
This flow illustrates the multi-path scanning approach used to balance performance with security-critical character escaping.
Sources: src/escape.ts:65-90
Encoding Components
- XML_BITSET_VALUE: A 32-bit integer used for rapid checks of ASCII characters (32-63) that require XML escaping:
",&,',<, and>. - xmlEncodeRegex: A global regular expression
/["&'<>\u0080-\uFFFF]/gthat catches XML specials and all non-ASCII characters.
Sources: src/escape.ts:28-39
Configuration and API Security
The library provides specific enums and interfaces to control the strictness of the encoding/decoding process, which directly impacts the security posture of the consuming application.
Decoding Modes
| Mode | Value | Security Implication |
|---|---|---|
Legacy | 0 | Decodes entities without semicolons; matches legacy browser behavior. |
Strict | 1 | Requires ; for all entities; safer for modern sanitizers. |
Attribute | 2 | Applies special termination rules for entities inside HTML attributes. |
Sources: src/decode.ts:74-84, src/index.ts:51-60
Error Handling
The EntityErrorProducer interface allows consumers to listen for character reference errors, such as:
missingSemicolonAfterCharacterReferenceabsenceOfDigitsInNumericCharacterReferencevalidateNumericCharacterReference(for numeric range checks)
Sources: src/decode.ts:89-96, src/decode.ts:245-255
Vulnerability Reporting
The project maintains a structured process for reporting security vulnerabilities to prevent public disclosure before a fix is available.
- Primary Channel: Use the Tidelift security contact.
- Secondary Channel: If Tidelift is unresponsive, use GitHub's private vulnerability reporting.
- Restriction: Users are explicitly requested NOT to open public GitHub issues for security vulnerabilities.
Sources: SECURITY.md:5-12, readme.md:118-121
Conclusion
The security of the entities library is achieved through a combination of high-performance data structures (Radix Trees), strict adherence to established web specifications (WHATWG), and a robust threat model that prioritizes the prevention of DoS and XSS. By providing granular decoding modes and validated encoding paths, it serves as a secure foundation for larger HTML/XML processing ecosystems.
Sources: SECURITY.md:27-41, src/decode.ts:446-450