Skip to main content

Security

VelinStyle is designed with security in mind. This page covers built-in protections, CSP compatibility, and best practices for safe usage.

XSS Protection in Web Components

Components that render dynamic content should use escapeHTML(), sanitizeURL(), or sanitizeSearchUrl. Icons use sanitizeSVG() (DOMPurify).

Demo only: <velin-secure-field> performs client-side encoding — never ship real secrets.

High-signal components

ComponentNotes
<velin-search>Escaped highlights; sanitized URLs
<velin-icon>SVG sanitized
<velin-email>Obfuscation only
<velin-lightbox>sanitizeURL
<velin-modal>, dialogs, toastsEscaped dynamic text

CSS Security Utilities

Built-in CSS classes for common security patterns.

.velin-user-content

A container that sandboxes user-generated content. It resets inherited styles, enables CSS containment, and hides dangerous elements like <script>, <iframe>, <object>, and elements with inline event handlers.

<div class="velin-user-content">
  <!-- Untrusted HTML goes here -->
  <p>User comment with <script>alert('xss')</script></p>
  <!-- The script tag is hidden via display: none !important -->
</div>
FeatureDescription
Style Resetall: initial prevents style inheritance from parent
CSS Containmentcontain: layout style paint isolates rendering
Dangerous Elementsscript, iframe, object, embed, applet hidden
Event HandlersElements with [onclick], [onload], [onerror] hidden
ImagesConstrained to max-width: 100%

.velin-secure-frame

CSS-level clickjacking protection. Content is hidden by default and only shown when stylesheets load (same-origin). Complement with HTTP X-Frame-Options: DENY or Content-Security-Policy: frame-ancestors 'none'.

<body class="velin-secure-frame">
  <!-- Content only visible when CSS loads -->
</body>

Autofill Protection

VelinStyle prevents browser autofill from leaking background colors that could expose data through CSS timing attacks.

External Link Indicator

Links with target="_blank" that lack rel="noopener" automatically receive a visual indicator (arrow icon) to warn users they're leaving the site.

Form Persistence Security

The <velin-persist> component includes multiple security measures:

FeatureDescription
Password exclusiontype="password" and type="file" fields are never saved
Key validationStorage keys must be alphanumeric, 1-64 chars (regex validated)
Size limitMaximum 64KB per entry prevents quota abuse
Quota handlingGraceful QuotaExceededError handling with event
Type validationRestored data must be a valid object (not string/null)
Session optionstorage="session" for data that shouldn't persist across sessions

Best Practices

  1. Never pass unsanitized user input to component methods or attributes. While VelinStyle escapes internally, defense-in-depth is critical.
  2. Use rel="noopener noreferrer" on all target="_blank" links to prevent tab-napping.
  3. Set CSP headers on your server. At minimum: default-src 'self'; style-src 'self' 'unsafe-inline'.
  4. Wrap user-generated content in .velin-user-content to sandbox rendering.
  5. Use storage="session" for <velin-persist> when handling sensitive form data that should not persist across browser sessions.
  6. Keep VelinStyle updated. Security patches are released as minor versions.
  7. For frameworks (React, Vue, Angular): These frameworks already escape by default. VelinStyle's escaping is an additional layer for vanilla JS usage.

PII scanner & email protection

Three layers: CLI scan, display obfuscation, optional form encryption (transport helper only — TLS required).

npx velinstyle scan --only pii
npx velinstyle scan --only pii --fix

Components

<velin-email value="contact@domain.com" label="Show email"></velin-email>
<velin-secure-field type="email" label="Email"></velin-secure-field>

Import secure field separately: import '@birdapi/velinstyle/secure'

Shadow DOM Encapsulation

All interactive Web Components use Shadow DOM (mode: "open") to encapsulate their internal styles and markup. This means:

  • Component styles do not leak into your page
  • Your page styles do not accidentally break components
  • Internal DOM structure is protected from accidental manipulation
  • Components with delegatesFocus: true (Modal, Drawer, Tabs, Dropdown) properly forward focus for accessibility
Note: mode: "open" means JavaScript can still access element.shadowRoot if needed (for testing or customization). This is intentional and matches standard Web Component library practice.

Theme waehlen