security: publish hardened v1 initiative snapshot
Publish the reviewed security policy and evidence, exact runtime ABI enforcement, orphan-output and permission safeguards, dead-upstream cleanup, and the evidence-gated v1 launch plan. This commit is an exact sanitized export from the private development record. Material implementation and review were assisted by OpenAI Codex; Cole Speelman reviewed the changes and accepts human responsibility. Himesan-Output-Permission: v1.0 Signed-off-by: Cole Speelman <gamertan@noreply.localhost>
This commit is contained in:
+167
-22
@@ -2,38 +2,183 @@
|
||||
|
||||
# Threat model
|
||||
|
||||
## Trusted
|
||||
This document separates demonstrated behavior from intended release work. It
|
||||
defines the boundary Sandwich Hime can reasonably defend; it is not a claim
|
||||
that the project or an application using it is universally secure.
|
||||
|
||||
- `.sando` files and embedded Go statements;
|
||||
- handwritten application Go;
|
||||
- explicit calls to `sando.TrustHTML`, `TrustURL`, `TrustJS`, and `TrustCSS`;
|
||||
- the selected compiler binary and runtime module version.
|
||||
## Security objective
|
||||
|
||||
## Untrusted
|
||||
For supported HTML contexts, data supplied to a compiler-generated component
|
||||
should remain data. It must not change HTML structure, create executable code,
|
||||
escape a quoted attribute, or introduce a disallowed URL scheme unless trusted
|
||||
application source makes an explicit security-sensitive decision.
|
||||
|
||||
- values supplied to components unless deliberately wrapped in a trusted type;
|
||||
That objective follows the same high-level model documented by Go's
|
||||
`html/template`: template authors are trusted while rendered data is not. The
|
||||
implementations and accepted languages differ. A systematic differential test
|
||||
campaign against `html/template` remains open work; current tests cover fixed
|
||||
adversarial cases and do not establish equivalence.
|
||||
|
||||
## Trusted capabilities
|
||||
|
||||
- `.sando` source, including its static markup and embedded Go statements;
|
||||
- handwritten application Go and values whose formatting methods execute Go;
|
||||
- handwritten implementations of `sando.Component`;
|
||||
- explicit `sando.TrustHTML`, `TrustURL`, `TrustJS`, and `TrustCSS` calls;
|
||||
- the selected compiler binary, Go toolchain, runtime module, and generated Go;
|
||||
- local project code built and executed by `himesan dev`; and
|
||||
- the user account, filesystem, environment, and other processes on the
|
||||
development workstation.
|
||||
|
||||
Template semantics become trusted source when built into an application;
|
||||
templates are not an untrusted-content sandbox. Someone allowed to edit one can
|
||||
execute ordinary Go through the application build and must receive the same
|
||||
trust as any other code contributor. Arbitrary or malformed template bytes
|
||||
remain adversarial input to compiler robustness while they are being inspected.
|
||||
|
||||
A handwritten `sando.Component` is a trusted output capability. It may write
|
||||
arbitrary bytes, change HTML parser context, recurse, block, panic, or perform
|
||||
side effects. Hime-generated components are independently checked for balanced
|
||||
HTML and may be inserted with `<?~` only at an HTML content boundary. The open
|
||||
Go interface does not extend that proof to handwritten implementations.
|
||||
|
||||
The `Trust*` constructors do not sanitize. They record that trusted application
|
||||
code accepts responsibility for the supplied bytes. `himesan check` emits
|
||||
best-effort lexical audit hints for direct constructor/type use visible inside
|
||||
`.sando` source; it is not Go type analysis, taint analysis, or a complete
|
||||
inventory of trust created transitively in handwritten Go.
|
||||
|
||||
## Untrusted inputs
|
||||
|
||||
- ordinary values supplied to generated components;
|
||||
- filenames and directory entries encountered during discovery;
|
||||
- stale or manually modified generated output;
|
||||
- missing, stale, or manually modified generated output;
|
||||
- browser requests reaching the development proxy;
|
||||
- child process output and health failures.
|
||||
- child-process output, exit behavior, and health failures; and
|
||||
- malformed template bytes from a repository being inspected, provided the
|
||||
template is not subsequently built and executed as trusted Go.
|
||||
|
||||
## Guarantees sought by v1
|
||||
## Demonstrated controls
|
||||
|
||||
- Context-sensitive escaping for supported HTML text, quoted attributes, URL attributes, and explicitly trusted script/style values.
|
||||
- Compilation failure for unsupported or ambiguous output contexts.
|
||||
- Dangerous normalized URL schemes fail rendering unless explicitly trusted.
|
||||
- Component calls cannot change the surrounding HTML parser context.
|
||||
- Dynamic `title` and `textarea` content uses a distinct RCDATA writer that escapes even `TrustedHTML`; trusted HTML cannot close those elements.
|
||||
- Writer failures propagate and partial output is visible to the caller as an error; applications can buffer when atomic responses matter.
|
||||
- Generation plans all outputs before atomic replacement, targets only owned files, preserves last-good output on failure, and follows neither symlinks nor nested-module traversal.
|
||||
- `generate` and `check` do not execute project code, invoke Go tooling, fetch dependencies, or alter `go.mod`.
|
||||
These are point-in-time implementation and test observations indexed to named
|
||||
commits in the evidence ledger, not continuous assurance.
|
||||
|
||||
- Untrusted dynamic output is accepted only in supported HTML text, quoted
|
||||
attribute, URL, and RCDATA contexts. Script and style interpolation requires
|
||||
an explicit `TrustedJS` or `TrustedCSS` capability.
|
||||
- Dynamic tag names, attribute names, unquoted values, event-handler values,
|
||||
style attributes, foreign SVG/MathML content, URL lists, `srcdoc`, meta
|
||||
refresh, malformed HTML, and ambiguous parser states are rejected.
|
||||
- Ordinary text and quoted attributes are escaped; `title` and `textarea` use
|
||||
an RCDATA writer that escapes every trusted wrapper as ordinary text.
|
||||
- Ordinary whole URL values are normalized and checked before any bytes are
|
||||
written. Schemes outside `http`, `https`, `mailto`, and `tel` fail unless a
|
||||
`TrustedURL` deliberately bypasses that check.
|
||||
- Writer errors and contract-violating short writes propagate to the caller.
|
||||
- All sources in one operation are parsed/context-checked/formatted in memory
|
||||
before the first output change. Each changed output is replaced atomically,
|
||||
and existing destinations lacking the generated-file ownership marker, plus
|
||||
symlink or non-regular destinations, are rejected. The marker prevents
|
||||
accidents; it is not authentication against a hostile local actor.
|
||||
- Recursive discovery skips VCS, vendor, symlink, nested-module, and detected
|
||||
filesystem boundaries. Explicit files are still subject to no-symlink and
|
||||
regular-file checks.
|
||||
- `generate` and `check` do not invoke the Go toolchain, fetch dependencies,
|
||||
execute project code, or edit `go.mod`. `himesan dev` is a separate command
|
||||
that intentionally does all of generate, build, and execute trusted project
|
||||
code.
|
||||
- The development proxy binds to a literal loopback address, validates Host
|
||||
authority, and checks Origin and Sec-Fetch-Site when those headers are
|
||||
present. These checks are hardening, not a user-authentication boundary. Its
|
||||
injected client is fixed and authorized with a hash rather than
|
||||
`unsafe-inline`.
|
||||
|
||||
Executable tests and their latest maintainer-observed results are indexed in
|
||||
[SECURITY_EVIDENCE.md](SECURITY_EVIDENCE.md).
|
||||
|
||||
## Important limits
|
||||
|
||||
### URLs
|
||||
|
||||
URL checking prevents disallowed or ambiguous schemes; it does not decide
|
||||
whether a destination is authorized or trustworthy. `https:` and relative URLs
|
||||
can still leave an origin, submit data, change a document base, or load active
|
||||
content depending on the element and attribute. Applications must validate
|
||||
destinations and apply tighter policy for sensitive sinks.
|
||||
|
||||
### Trusted raw values
|
||||
|
||||
`TrustedHTML`, `TrustedJS`, and `TrustedCSS` are intentional escape hatches.
|
||||
Their authors must preserve the surrounding HTML parser state, including
|
||||
container-closing and legacy parser-transition sequences. Prefer ordinary data,
|
||||
keep trust conversion beside its validator, and review each use manually.
|
||||
|
||||
### Rendering resources and failures
|
||||
|
||||
The runtime does not impose output-size, recursion, CPU, allocation, or time
|
||||
limits; recover panics; or make an arbitrary `io.Writer` transactional.
|
||||
Applications should render into a buffer when an all-or-error HTTP body matters
|
||||
and should apply their own request deadlines, bounded writers, input limits, and
|
||||
panic policy. A context is passed through components, but generated output does
|
||||
not automatically stop between writes when it is canceled.
|
||||
|
||||
The compiler likewise has no hard source-size, memory, or compile-time budget.
|
||||
Run it only against repositories whose resource use the caller is willing to
|
||||
accept.
|
||||
|
||||
### Filesystem concurrency
|
||||
|
||||
Discovery and generation defend against symlinks and non-regular files observed
|
||||
at their checks. They are not currently a security boundary against a hostile
|
||||
local actor racing path components between inspection and use. Run the compiler
|
||||
inside a trusted workspace and user account. Atomic replacement describes each
|
||||
file's visibility; a multi-file generation is not a filesystem transaction if
|
||||
a later replacement fails.
|
||||
|
||||
The watcher is a development convenience, not a filesystem-integrity monitor.
|
||||
It may miss adversarial changes engineered to preserve the metadata it samples.
|
||||
|
||||
### Development supervisor
|
||||
|
||||
Loopback is host-local, not user-local. The development supervisor has no user
|
||||
authentication boundary against another process/account on the workstation. It
|
||||
builds and executes project code with the user's inherited environment and may
|
||||
fetch dependencies according to the user's Go configuration. It is not a
|
||||
production proxy, public preview host, TLS terminator, deployment system, or
|
||||
safe runner for untrusted repositories.
|
||||
|
||||
The watcher scans configured trees and eligible HTML responses may be buffered
|
||||
up to 16 MiB for reload injection. The application and operating system retain
|
||||
responsibility for request, response, SSE, file-count, and process resource
|
||||
limits.
|
||||
|
||||
Development CSP rewriting is reload convenience, not production CSP
|
||||
validation. Process cleanup is best-effort; a deliberately detached descendant
|
||||
may outlive the process tree the supervisor can identify. Human-readable
|
||||
diagnostics may also contain filenames or child-tool output supplied by a local
|
||||
repository, so terminals and log consumers remain part of the trusted
|
||||
development environment.
|
||||
|
||||
## Non-goals
|
||||
|
||||
Templates are not a sandbox. A malicious template author can write malicious Go in a statement tag. Sandwich Hime does not validate business authorization, prevent unsafe application logic, make an arbitrary `io.Writer` transactional, or secure an application router/server. Trusted constructors are intentionally sharp tools and must remain conspicuous in review and `himesan check` reporting. A `TrustedHTML` fragment must be balanced and context-neutral; `TrustedJS` and `TrustedCSS` authors are responsible for excluding container-closing HTML sequences.
|
||||
Sandwich Hime does not:
|
||||
|
||||
The v1 HTML state machine is deliberately smaller than a browser parser. Any construct it cannot prove safe is rejected rather than guessed. Differential testing against Go `html/template` is a baseline, not a claim of byte-identical output or universal parser equivalence.
|
||||
- sandbox template authors or embedded Go;
|
||||
- sanitize arbitrary trusted HTML, JavaScript, CSS, or URLs;
|
||||
- provide application authentication, authorization, CSRF policy, CSP, routing,
|
||||
database security, TLS, caching, or production process isolation;
|
||||
- type-check all embedded Go during `himesan check` (the normal Go build/test
|
||||
remains required);
|
||||
- detect every dynamic or handwritten component cycle;
|
||||
- guarantee safety under hostile concurrent mutation of the workspace; or
|
||||
- replace independent review, browser testing, vulnerability response, or the
|
||||
consuming application's threat model.
|
||||
|
||||
## Principal attack classes
|
||||
## Open release work
|
||||
|
||||
Tests cover delimiter confusion, malformed HTML, quote/entity injection, event attributes, dangerous and obfuscated URLs, script/style termination, Unicode and NUL handling, component context breaks, import/source-map injection, CRLF and path behavior, symlinks, nested modules, stale outputs, interrupted/read-only writes, writer failures, component cycles, development-proxy exposure, CSP weakening, compression/content-length mistakes, and orphaned child processes.
|
||||
- broaden semantic and browser-parser differential testing;
|
||||
- execute the native Windows/macOS security and process-lifecycle matrix;
|
||||
- complete signed release provenance, checksums, and SBOM evidence;
|
||||
- test the confidential reporting and signing-key recovery procedures; and
|
||||
- close or explicitly accept every finding listed in the evidence ledger before
|
||||
assigning a supported release line.
|
||||
|
||||
Reference in New Issue
Block a user