Review output encoding where user content renders
Trace user-controlled values into text, attributes, links, and rich content. Build rendering assertions that preserve valid text without allowing execution.
Review output encoding at the place a value enters the page. A database field marked validated can still be unsafe when a later feature inserts it into a different context. Trace a concrete value, such as a project name, through its normal view, notification, search result, and administrative preview.
OWASP's output handling guidance distinguishes HTML, attribute, URL, and script contexts. Use the framework's safe rendering path where possible. Rich HTML requires a separate sanitization decision.
Create a rendering-context inventory
Record the source field, renderer, intended meaning, and library responsible for protection. Include server-rendered pages and client updates. One safe implementation does not cover a second component that converts the same value into markup.
| Destination | Intended value | Review decision |
|---|---|---|
| Visible project title | Plain text | Render through the framework text path |
| Ordinary text attribute | Label | Keep the attribute name fixed |
| Link destination | Approved URL | Validate the scheme and destination before rendering |
| Rich description | Limited formatting | Use a maintained sanitizer with a reviewed allowlist |
| Executable script | Application code | Do not interpolate user content as code |
Separate storage representation from display protection. Encoding text before storage can lead to double encoding without protecting a later unsafe use.
Write assertions for meaning and execution
Use harmless synthetic strings with quotes, angle brackets, ampersands, and non-ASCII text. Assert that the visible value remains correct. Also assert that the renderer does not create unexpected elements, event attributes, or executable destinations.
Exercise saved content as well as immediate previews. A preview may use a safe component while a report export uses string concatenation. For rich text, test the allowed formatting and rejected structures independently. Otherwise a fix that deletes all content can appear successful.
Review escape hatches as code
Search the relevant application for raw HTML insertion, manual template assembly, and custom Markdown plugins. Examine the data passed to each occurrence rather than assuming every occurrence is exploitable. Keep trusted static templates separate from user-controlled fragments.
After a change, inspect the rendered DOM in a permitted test session and run the stored-content regression. Record the renderer version and sanitizer configuration with the test. Avoid modifying sanitized output with a later unsafe parser. The completion criterion is specific: intended text and formatting remain readable, while the tested input cannot create executable page behavior through that rendering path.
Find the gaps before your next launch
Use the release checklist to identify changed security boundaries and missing evidence. Discuss the application paths you want reviewed before launch.