Security Boundaries and Safe Rendering
Framework Responsibilities
SimplyPages provides safe defaults in core rendering paths.
- Text output is escaped by default.
- Attribute values are encoded; malformed tag/attribute names are rejected.
- Encoding does not validate URL schemes, event-handler code, or raw style attributes. Generic attribute values remain application-controlled.
- Slot text output is escaped.
- Inline styles added through
addStyle(...)reject declaration-breakout characters and replace only exact property names.
URL classification is method-specific
Link constructors, create and withHref allow http, https, mailto, tel
and the existing relative/protocol-relative forms. Image constructors, factories and
withSrc reject javascript: and data: without an image prefix, but retain other
schemes, including custom schemes, FTP and blob URLs. A data:image/ prefix is not
MIME or payload inspection, including for SVG.
These methods classify a view with boundary C0 controls/ASCII space trimmed, TAB/LF/CR
removed, and ASCII letters case-folded independently of locale. Thus an actual TAB in
ht<TAB>tp: or data:im<TAB>age/ can produce an accepted spelling. Getters and emitted
attributes retain the original string through ordinary HTML encoding. There is no
entity/percent decoding or Unicode normalization. This is scheme classification,
not destination authorization, same-origin enforcement, SSRF protection or a promise
that a URL loads safely.
Other URL conveniences require application-controlled or separately context-validated
values. This includes Dropdown links; AccountWidget destinations/dynamic endpoints;
NavBar, SideNav and Breadcrumb entries (including public nested entry constructors and
utility links); TopNavBuilder/SideNavBuilder links and aliases; Hero CTA links; Card/Gallery
image sources; Audio/Video sources and video posters; Form actions/HTMX/CSRF URLs and
FormModule submit URLs. Generic withAttribute, inherited HTMX methods and Link's HTMX
helpers do not apply the href/src validators. Generic replacement can change a Link/Image
attribute without changing its getter. Template compilation does not add validation.
Two existing delegated paths differ: AccountBarBuilder link conveniences construct Link
immediately; BannerBuilder's ordinary horizontal image constructs Image when generated
content is built. Dynamic endpoints and CSS backgrounds do not share those checks. Default
forum avatar handling uses its existing Image/fallback path, not a new global URL policy.
CSS values need their own trust boundary
HtmlTag.addStyle checks property names and rejects declaration-breakout characters in
values. It is not a semantic CSS or URL sanitizer. addTrustedStyle bypasses that value
check; Style.addInlineStyle and raw style attributes retain declaration separators.
Supply application-controlled values or validate for the actual CSS context. Width helpers
have a separate, narrower size-token grammar.
Banner/Hero background-image methods interpolate into a single-quoted CSS url() without
CSS escaping. Image validation alone does not control quotes, backslashes or declaration
syntax there. Banner background/text colors, Hero/AccountBar background colors,
Spacer.custom and ProgressBar.withHeight also assemble raw styles. HTML attribute
encoding prevents markup breakout, not CSS declaration breakout or unsafe CSS semantics.
Application Responsibilities
Your application must enforce:
- Authentication
- Authorization
- CSRF protections
- Input validation
- Business authorization checks
For editing flows, UI-level affordances are not an authorization boundary. Controllers or service handlers must re-check edit/delete/create permissions on every HTMX endpoint, including nested child edit endpoints.
Unsafe HTML
withUnsafeHtml(...) is intentionally dangerous.
Use only with trusted, sanitized sources.
Never pass raw user input.
addTrustedStyle(...) is also a trusted-input path. Use it only when a known-safe value needs CSS syntax that the hardened addStyle(...) path rejects, such as a trusted data URL.
URL Safety
Apply the method-specific classification rules rather than assuming every helper uses Link's allowlist. In particular, Hero/Banner CSS backgrounds require application-owned CSS syntax and destination validation as described above.
HTMX-Specific Security
- Apply the same auth checks on HTMX endpoints as full-page endpoints.
- Include CSRF token handling on state-changing requests.
- Return controlled HTML fragments on auth failures.
- Validate path variables and reject invalid row positions or child identifiers before mutation.
- Do not pre-escape persisted form text; rely on SimplyPages render paths to escape plain text once at output time.
Quick Checklist
- No untrusted input to
withUnsafeHtml. - No unvalidated raw URLs when building anchors manually.
- Validation before persistence.
- Authorization before edit/delete/update.
- No hidden admin operations behind client-only controls.