Skip to content

Security: php-forge/vite

docs/security.md

Security and CSP

HTML escaping

HtmlRenderer delegates tag construction and HTML5 attribute escaping to ui-awesome/html. Invalid UTF-8 bytes are substituted rather than passed through. Required attributes such as src, href, rel, type, and nonce cannot be overridden.

Inline module source is application-owned executable JavaScript, not untrusted text. The renderer prevents a literal case-insensitive </script sequence from terminating the script element, but it does not sanitize JavaScript. Never build an InlineModule by interpolating untrusted input without a safe JavaScript serialization strategy.

Custom attribute policy

HtmlRenderOptions accepts per-asset-type attributes and an optional per-asset callback:

use PHPForge\Vite\Asset\AssetInterface;
use PHPForge\Vite\Asset\ModuleScript;
use PHPForge\Vite\Html\HtmlRenderOptions;

$options = HtmlRenderOptions::create()
    ->withModuleScriptAttributes(['crossorigin' => true])
    ->withStylesheetAttributes(['media' => 'screen'])
    ->withAttributeProvider(
        static fn(AssetInterface $asset): array => $asset instanceof ModuleScript
            ? ['data-entry' => 'application']
            : [],
    );

Names must start with a letter or underscore and continue with letters, digits, underscores or hyphens. Values may be strings, integers, floats, booleans or null: true emits a valueless attribute, false and null omit it. Inline event handlers, style, required renderer attributes, nonce overrides and duplicate names (case-insensitive) are rejected.

A callback value replaces a per-type value with the same key.

CSP nonce

Generate a cryptographically random nonce for each HTTP response, include it in the application's Content-Security-Policy header, and pass the same base64 or base64url value to the renderer:

use PHPForge\Vite\Html\HtmlRenderer;
use PHPForge\Vite\Html\HtmlRenderOptions;

$nonce = base64_encode(random_bytes(18));

header("Content-Security-Policy: script-src 'nonce-{$nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none'");

$html = HtmlRenderer::create()->render(
    $vite->resolve(),
    HtmlRenderOptions::create()->withNonce($nonce),
);

The renderer places the nonce on every generated script and link tag. The complete CSP header, the per-response nonce lifecycle and every other directive stay with the application.

Dev servers usually need extra connect-src origins for HTTP and WebSocket HMR. Add those to the application's development policy only; this package never weakens CSP on its own.


← Back to documentation

There aren't any published security advisories