Skip to content

Security Guidance

What this guide is: A practical security checklist for the design-system surfaces most likely to handle untrusted or sensitive content.

Why it matters: Reusable UI often becomes the last mile for dangerous data. If the docs only say “render HTML here” without guardrails, junior engineers can ship XSS or secret-leak bugs by accident.

Who this is for: Feature engineers, reviewers, and anyone copying design-system examples into an app.

The short version

  • Treat all user input as untrusted.
  • Sanitize HTML before rendering it.
  • Never log secrets just because a debug panel can show them.
  • Validate files and URLs on the server, not only in the browser.

Rich text

The RichText component renders HTML content. Always sanitize HTML before passing it in.

import DOMPurify from "dompurify";
import { RichText } from "@dmwd-io/design-system";
const clean = DOMPurify.sanitize(userHtml, {
ALLOWED_TAGS: ["b", "i", "em", "strong", "p", "br"],
});
<RichText content={clean} />;

Good rule of thumb: if a string came from a user, a CMS, a markdown converter, or an external API, assume you need to sanitize it.

Log and terminal output

Components like LogViewer and PodTerminal can display sensitive operational data.

  • Redact tokens, passwords, cookies, and PII before rendering.
  • Treat copy-to-clipboard as a security decision, not just a convenience feature.
  • Verify malformed ANSI escape sequences do not break rendering or create misleading output.

Code viewer

CodeViewer shows code; it does not make code safe.

  • Do not assume syntax highlighting is equivalent to sanitization.
  • If code content came from users or external systems, validate the rendering path before exposing it broadly.
  • Keep “view source” components display-only unless you have a separate, reviewed execution model.
  • Validate user-provided URLs before using them as href values.
  • Guard against javascript: URLs and other dangerous schemes.
  • For external links, use rel="noopener noreferrer" when opening a new tab.
  • If you use asChild, make sure the delegated element still preserves the security behavior you expect.

User-supplied files

The FileDropzone component helps collect files. It does not make files safe.

  • Validate file type and size on the server.
  • Treat MIME types as hints, not proof.
  • Render file metadata as text, not HTML.
  • Scan or quarantine risky uploads according to your application’s threat model.

Content Security Policy

The component library is compatible with a strict CSP because it does not rely on inline style attributes for normal rendering. Some integrated tools, such as Monaco-based code editors, may need extra worker or script allowances. Test those cases explicitly in the consuming app.

Best practices

  • Start from least privilege.
  • Default to escaping, sanitizing, and validating.
  • Keep security-sensitive examples commented and explicit so copy-paste use stays safe.
  • When you are unsure, ask for a security review before widening the surface.