Skip to main content
VelinStyle v0.8.0
⌂ Home
  1. Docs
  2. Extend
  3. Security

Security

VelinStyle takes security seriously — XSS protection is built into every Web Component, CSS utilities sandbox user content, and the CLI scan command flags common XSS and accessibility issues in your own HTML/JS/CSS (see rule table). Use HTTP CSP and Trusted Types for defense in depth.

XSS Protection

All nine Web Components are hardened against cross-site scripting. Every component that renders dynamic content passes values through escapeHTML() and sanitizeURL() from components/sanitize.js.

Protected components

ComponentSanitization
<velin-toast>escapeHTML() on message content
<velin-dialog>escapeHTML() on title & body
<velin-lightbox>sanitizeURL() on image sources, escapeHTML() on captions
<velin-countdown>escapeHTML() on label attributes
<velin-stepper-wc>escapeHTML() on step labels
<velin-tooltip-wc>escapeHTML() on tooltip text
<velin-popover>escapeHTML() on title & content
<velin-drawer>escapeHTML() on heading
<velin-modal>escapeHTML() on title, sanitizeURL() on action links

How it works

import { escapeHTML, sanitizeURL } from './sanitize.js';

// escapeHTML replaces <, >, &, ", and ' with HTML entities
escapeHTML('<img onerror=alert(1)>');
// → "&lt;img onerror=alert(1)&gt;"

// sanitizeURL blocks javascript: and data: URIs
sanitizeURL('javascript:alert(1)'); // → ""
sanitizeURL('https://example.com'); // → "https://example.com"

CSP Compatibility

VelinStyle is designed to work with strict Content-Security-Policy headers. No inline style attributes are injected at runtime, and all Web Components use shadow DOM or class-based styling.

Recommended headers

Content-Security-Policy:
  default-src 'self';
  script-src  'self';
  style-src   'self' 'unsafe-inline';
  img-src     'self' data:;
  font-src    'self';

Trusted Types

VelinStyle exposes getTrustedPolicy() for environments that enforce Trusted Types. Wrap your HTML assignments with the returned policy to stay compliant:

import { getTrustedPolicy } from 'velinstyle';

const policy = getTrustedPolicy();
element.innerHTML = policy.createHTML(safeContent);

CSS Security Utilities

The stylesheet src/a11y/security.css provides defensive CSS classes that mitigate common web vulnerabilities without JavaScript.

.velin-user-content

Apply to any container that renders untrusted or user-generated content. It sandboxes the content by blocking scripts, iframes, object embeds, and inline event handlers via CSS containment.

<div class="velin-user-content">
  <!-- User-generated HTML goes here -->
  <!-- Scripts, iframes, and event handlers are neutralized -->
</div>

.velin-secure-frame

Provides clickjacking protection for embedded frames by ensuring the frame cannot be overlaid with invisible elements.

<iframe class="velin-secure-frame" src="..."></iframe>

External link indicator

Links with target="_blank" that are missing rel="noopener" automatically receive a visual warning indicator, reminding developers to add the attribute:

/* security.css — flags unsafe external links */
a[target="_blank"]:not([rel~="noopener"])::after {
  content: " ⚠";
  color: var(--velin-color-warning);
}

Autofill & paste-jacking prevention

Password fields are protected against browser autofill abuse, and paste-jacking attacks are mitigated by blocking invisible clipboard-hijacking overlays within .velin-user-content containers.

Form Persistence Security

The velin-persist module stores form data in localStorage for convenience — but it is hardened against abuse:

ProtectionDetail
Key validationStorage keys must be alphanumeric (plus hyphens/underscores), max 64 characters. Invalid keys are rejected silently.
Size limitEach entry is capped at 64 KB. Larger payloads are discarded to prevent localStorage flooding.
QuotaExceededErrorCaught and handled gracefully — the user is not shown a raw browser error.
Sensitive fields excludedFields with type="password" and type="file" are never persisted.
<!-- Password and file fields are automatically excluded -->
<form data-velin-persist="signup">
  <input type="text" name="username">     <!-- ✓ persisted -->
  <input type="email" name="email">        <!-- ✓ persisted -->
  <input type="password" name="password">  <!-- ✗ excluded -->
  <input type="file" name="avatar">        <!-- ✗ excluded -->
</form>

Security Scanner

VelinStyle ships with a built-in velinstyle scan CLI command that checks your project for common security issues:

npx velinstyle scan

# Example output:
# ✓ All components use escapeHTML()
# ✓ No inline event handlers found
# ⚠ 2 links missing rel="noopener"  (src/page.html:14, src/page.html:28)
# ✓ CSP meta tag present
# ✓ No raw innerHTML assignments

See the CLI documentation for the full list of scan rules and configuration options.

Best Practices

A quick security checklist for VelinStyle projects:

Theme wählen