HTML and security

Markdown allows raw HTML in the source, and LibreTimes keeps a controlled subset of it. Everything a document renders – Markdown-generated and hand-written HTML alike – passes through sanitization on an allowlist basis: what is not explicitly allowed is removed.

Raw HTML you can use

Markdown syntax covers almost everything, so raw HTML is rarely needed. The useful allowed cases:

ElementWhy you might write it
<details> / <summary>collapsible section; same result as the spoiler directive
<sub> / <sup>subscript/superscript, equivalent to ~x~ / ^x^
<mark>highlight, equivalent to ==x==
<kbd>keyboard keys: Ctrl+K
<table>, <thead>, <tbody>, <tr>, <th>, <td>tables that need rowspan/colspan beyond GFM syntax
<img width="..." height="...">an image with explicit dimensions
<br>, <hr>, <blockquote>, <dl>/<dt>/<dd>standard structure, same as their Markdown forms

Standard inline and block elements (<b>, <i>, <em>, <strong>, <code>, <pre>, <p>, <ul>, <ol>, <li>, headings, and similar) are allowed too – prefer the Markdown forms for readability.

What sanitization removes

  • Scripts and handlers: <script>, <style>, and every on* event attribute. There is no way to execute code from a document.
  • Dangerous URLs: link hrefs outside https/http/mailto and image srcs outside https/http (no javascript:, no data:).
  • Frames: <iframe> survives only as produced by video embeds, with src restricted to youtube-nocookie.com and player.vimeo.com. Any other frame is removed entirely.
  • Free-form styling: style attributes, with a pinned exception for the video player's own sizing. A document cannot restyle the page around it.
  • Everything unlisted: <form>, <input>, <object>, <embed>, <canvas>, custom elements – removed, along with unlisted attributes on allowed elements.

Removal is silent: the disallowed node disappears from the rendered page rather than producing an error.

Notes for authors

  • Element ids you write in raw HTML are prefixed with user-content- in the output (a standard defense against DOM clobbering). Heading anchors are generated automatically, so you rarely need your own ids.
  • If something you wrote is missing from the rendered page, it was most likely sanitized. Check this page's lists; the Markdown-native form of the same structure is usually the answer.
  • Sanitization is not a substitute for judgment about content – it stops code, not claims. Community standards live in the acceptable use policy.