Security and accessibility
Security & Accessibility
XSS Protection
UI Patterns inherits SDC's rendering pipeline, which means:
- String props with
contentMediaType: text/htmlpass throughMarkup::create()during preprocessing, marking them as safe HTML. Ensure the source data is already sanitized. - String props with
contentMediaType: text/plainare run throughstrip_tags()during normalization, providing automatic XSS protection. - Slot content passes through Drupal's render API, which auto-escapes by default via Twig's autoescape.
- Token replacement uses
Token::replacePlain()for non-markup contexts andToken::replace()with['clear' => TRUE]for markup, preventing unresolved tokens from appearing.
Sanitization Best Practices
# For user-visible text that should never contain HTML:
description:
title: "Description"
type: "string"
contentMediaType: "text/plain" # strip_tags() applied
# For rich text content:
# Use a slot instead of a string prop
slots:
body:
title: "Body content"
Block Source Security
The BlockSource filters dangerous blocks via hook_plugin_filter_block__ui_patterns_alter():
- inline_block is excluded (prevents config-to-content dependencies)
- system_main_block and page_title_block are excluded (Layout Builder convention)
- layout_builder and ui_patterns_blocks provider blocks are excluded (prevents recursion)
Attributes and Injection
The attributes prop type accepts arbitrary key-value pairs. This is safe because Drupal's Attribute class escapes attribute values during rendering. However:
- Never pass
attributesvalues directly into JavaScript contexts without escaping - The
class_attributewidget provides a safer interface for CSS-only attribute input
Accessibility Considerations
- Always use the
attributesprop on wrapper elements. Accessibility tools injectaria-*attributes through this mechanism. - Provide meaningful titles for all props and slots. These become form labels for screen reader users configuring components.
- Use semantic HTML in component templates. UI Patterns does not enforce semantics; that responsibility stays with the component author.
- Support keyboard navigation in interactive components. UI Patterns handles the data layer; interaction patterns are the template's responsibility.
- Mark decorative slots as optional in the component definition. Required slots that may be empty create broken layouts for assistive technology users.
Content Security Policy (CSP)
UI Patterns does not add inline scripts or styles. Components should follow the same CSP guidelines as any Drupal theme component. If a component needs JavaScript, attach it via the Drupal library system, not inline scripts.
Common Mistakes
| Mistake | Why It Is Wrong |
|---|---|
Using Markup::create() on user input |
This marks content as safe, bypassing Twig's autoescape. Only use it on already-sanitized content. UI Patterns' StringPropType does this in preprocess() because normalization has already occurred. |
Skipping attributes on the wrapper element |
Drupal modules that add data-* attributes for contextual links, quick edit, and accessibility features will silently fail. |
Not setting contentMediaType: text/plain for plain text props |
Without it, string props allow HTML, which may be unexpected if the value comes from user input. |
See Also
- Drupal Security Guide
- Best Practices & Anti-Patterns