# Security Policy ## Reporting a vulnerability Please do not open public GitHub issues for security findings. Instead, use one of these private channels: - **GitHub Security Advisory** (preferred). From the repo's "Security" tab, click "Report a vulnerability." This creates a private advisory visible only to maintainers. - **Email**: send to the maintainer via the contact listed on the maintainer profile at [github.com/heyoub](https://github.com/heyoub). When reporting, please include: - The affected package and version - A minimal reproduction (code snippet, repro repo, or `pnpm pack`-installed consumer demonstrating the issue) - The impact you've observed and any thoughts on scope - Whether you're willing to be credited in the advisory once published We aim to acknowledge reports within 72 hours and ship a fix or mitigation within 14 days for high-severity findings. Pre-1.0 means we may resolve some issues with a breaking change rather than a workaround; we'll communicate which path before we ship. ## Supported versions LiteShip is pre-1.0. The latest minor release on the `main` branch is the only supported line. Older versions may receive security fixes at maintainer discretion if the fix is trivial to backport. | Version | Supported | | --- | --- | | `0.x` (latest minor) | yes | | Older `0.x` | best-effort backport on request | ## Security posture (summary) Trust is set explicitly, not by permission default: - **Runtime URL allowlist.** Runtime URLs are same-origin by default; cross-origin requires an explicit allowlist policy before the line is run. The allowlist resolver runs a hostname-string blocklist for private/link-local IP literals via `isPrivateOrReservedIP` (`packages/web/src/security/runtime-url.ts:187`), covering RFC 1918, link-local, CG-NAT, `127/8`, `0/8`, and IPv6 unique-local / loopback ranges as literal addresses. **The check operates on the literal hostname, not on the post-DNS-resolution IP.** A hostname like `internal.example.com` that resolves to a private range will pass this check. For DNS-rebinding-class threats, restrict outbound resolution at the network layer (split-horizon DNS or a server-side egress firewall) — LiteShip alone does not defend against attacker-controlled DNS. - **Artifact ID validation.** IDs are validated as single path segments (`packages/web/src/stream/sse-pure.ts`, `buildUrl`), preventing path-traversal attempts via runtime URL construction. - **HTML trust pipeline.** Stream and LLM HTML flows route through a shared trust gate (`packages/web/src/security/html-trust.ts`) with three modes: `text` (default, no HTML), `sanitized-html` (strips a tag-name blocklist — `script`, `style`, `iframe`, `object`, `embed`, `svg`, `math`, `base`, `meta`, `link`, `noscript`, `form` — plus event-handler attributes, `srcdoc` / `style`, and `javascript:` / `data:text/html` / `data:text/javascript` / `data:application/x-javascript` schemes on url-sink attributes (`href`, `src`, `xlink:href`, `action`, `formaction`, `ping`, `background`, `cite`, `data`, `poster`)), and explicit `trusted-html` (caller asserts via an opt-in flag, otherwise downgrades to `sanitized-html`). The DOM morph routes through this same pipeline at `packages/web/src/morph/diff-pure.ts:30` (`createHtmlFragment(html, { policy: 'sanitized-html' })`); there is no third unguarded `innerHTML` path. Parsing happens via `