A business commissioning a CMS may want bold text and links without granting authors the ability to run scripts. “We escape everything” and “the editor produces HTML” answer different requirements. Agree the allowed rich-text vocabulary, the maintained sanitisation layer and what happens after it runs.
Primary evidence and claim boundaries
OWASP recommends HTML sanitisation when intended rich HTML must render, and warns that modifying the result afterwards can invalidate that protection. Context-aware output encoding is appropriate when displaying plain text. Primary reference · Read 18 October 2026.
Filled acceptance example
Original synthetic teaching scenario, not a client case, provider integration test or business result. The example policy needs the actual owner’s approval; scroll the table on narrow screens.
| Input and state | Declared check | Expected output and decision |
|---|---|---|
| Approved vocabulary:p,strong,a with reviewed URL schemes | Author supplies<strong>Offer</strong> | Retain formatting only through maintained approved sanitizer |
| Plain customer reference field | Input contains literal< and > | Show characters as text; do not turn it into rich HTML |
| Sanitized fragment | Later library adds event attributes | Reject pipeline; earlier sanitisation is no longer enough |
| Input has an unapproved embedded iframe | No approved embed contract | Reject or remove under policy; never assume editor trust |
Practical handover procedure
- Write separate policies for plain text, rich text and approved embeds. Give the supplier benign formatting examples plus inert strings representing disallowed elements and attributes.
- Ask the supplier to retain raw input and redacted final output in an isolated authorised test. Compare preserved meaning, removed capabilities and every transformation after sanitisation.
- Record sanitizer/version/maintenance responsibility and test the actual output context with qualified security review. Do not ship a regular-expression replacement as a general sanitizer.
Interpret the outcome
The table is a concrete output-policy decision, not an executable sanitizer. Its original boundary prevents two opposite defects: rendering plain references as HTML and destroying all legitimate CMS formatting. The third row requires review of the entire pipeline rather than one library badge.
Acceptance decision
Require the agreed safe representation and retained meaning for each supplied case, plus implementation-specific security evidence. Missing sanitizer or a post-sanitisation mutation blocks component acceptance.
Limits and unverified work
Inert synthetic strings only; no exploit is executed and no general-purpose sanitizer or security certification is supplied. The actual maintained implementation remains the supplier’s responsibility.
Download the filled bilingual acceptance record — Contains the inputs, steps, expectations and limits. This is a teaching record, not an executable production integration.