FIELD NOTES · ACCEPTANCE EXERCISES

Rich text needs a declared output boundary

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 stateDeclared checkExpected output and decision
Approved vocabulary:p,strong,a with reviewed URL schemesAuthor supplies<strong>Offer</strong>Retain formatting only through maintained approved sanitizer
Plain customer reference fieldInput contains literal< and >Show characters as text; do not turn it into rich HTML
Sanitized fragmentLater library adds event attributesReject pipeline; earlier sanitisation is no longer enough
Input has an unapproved embedded iframeNo approved embed contractReject or remove under policy; never assume editor trust

Practical handover procedure

  1. 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.
  2. 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.
  3. 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.