v0.24.5
This commit is contained in:
commit
5e23e9af02
240 files changed
+99957
No files matched your search
@@ -0,0 +1,207 @@
|
||||
# Security model and limitations
|
||||
|
||||
This is a development source release with no executed Rust integration results in
|
||||
the packaging environment. Do not expose it as a production security boundary until
|
||||
the actual build, protocol tests, deployment review and an appropriate security
|
||||
assessment have passed.
|
||||
|
||||
## Administration
|
||||
|
||||
Administration binds to loopback HTTP by default. Settings can enable a dedicated
|
||||
administration HTTPS listener, choose the application-managed certificate or a
|
||||
certificate from the inventory, persist a non-loopback bind and allow explicit DNS
|
||||
Host/Origin names. Remote persisted binding is accepted only with administration TLS.
|
||||
An explicit startup `--allow-remote-admin` can expose plain HTTP on a non-loopback address;
|
||||
that path should remain behind a trusted firewall/private network boundary.
|
||||
Passwords use salted Argon2id; password work has admission limits and runs off the
|
||||
network I/O path. Setup requires local filesystem authority or the one-time random
|
||||
capability. No default administrator/password is created.
|
||||
|
||||
Sessions have HttpOnly/SameSite=Strict cookies, idle and absolute expiries and
|
||||
credential-generation revocation. Mutations require scheme-aware Host/Origin checks,
|
||||
the request marker and a CSRF token. Local CLI reset changes the hash and invalidates
|
||||
all existing sessions without editing SQLite manually. Administration HTTPS marks the
|
||||
session cookie Secure; HTTP cannot. The admin certificate and bind changes are
|
||||
restart-required. A dedicated metrics credential is separate from browser sessions.
|
||||
|
||||
The data directory and SQLite files are private. The local OS user with data-directory
|
||||
access is a recovery authority and can create short-lived CLI sessions. Protect that
|
||||
account, filesystem and backup copies; browser authentication does not defend against
|
||||
a compromised process owner. `.env` is trusted shell code, never untrusted input.
|
||||
|
||||
## Backend and routing boundary
|
||||
|
||||
Only configured HTTP/HTTPS origins may be dialed. Absolute-form client targets and
|
||||
CONNECT cannot turn the proxy into an unrestricted forward proxy. ACL is evaluated
|
||||
before new TCP/TLS connections and before reuse of an existing upstream connection.
|
||||
Host and route restrictions combine; route allow cannot override host deny.
|
||||
Forwarded headers are rebuilt from socket identity by default. An explicit
|
||||
trusted-proxy CIDR policy can accept a bounded existing chain and derive the client
|
||||
IP for ACL/affinity; see INTEGRATIONS_040.md. Routing still uses the actual local
|
||||
destination, never any forwarded address or host.
|
||||
|
||||
Private/loopback destinations require explicit approval. DNS answers pass the same
|
||||
policy and optional per-backend CIDR restriction; an unsafe answer fails the entire
|
||||
resolution. Validated results are used without a second DNS lookup. Special-address
|
||||
blocks include common metadata/link-local targets and normalize mapped IPv6.
|
||||
Listener self-target restrictions prevent simple loops and control-plane access by
|
||||
default. A privileged administrator can deliberately set `accept_local_listener_risk=true`
|
||||
on one backend; private/loopback destinations additionally require `allow_private=true`.
|
||||
This is intended for consciously accepted local-listener use (including port 9090) and
|
||||
can create a request loop or expose administration through a public vhost. It does not
|
||||
relax metadata/link-local/special-address filtering or CIDR restrictions. Keep network
|
||||
egress and frontend ACLs as defense in depth.
|
||||
|
||||
No backend `Location` redirect is followed internally. HTTPS transport encryption remains
|
||||
available, but backend trust/hostname verification is off by default. Set `tls_verify: true`
|
||||
for origins where certificate-chain and hostname authentication is required. With
|
||||
verification disabled, a network attacker able to intercept that route may impersonate
|
||||
the origin. Address/DNS restrictions still apply; the local-listener exception exists only
|
||||
when explicitly accepted as above. Operator-supplied backend configuration is privileged
|
||||
configuration, not a field that an unauthenticated caller can edit.
|
||||
|
||||
## TLS and tunnels
|
||||
|
||||
Private key files are size-bounded, regular files, owner-only on POSIX and opened
|
||||
without following final-component symlinks. Named files cannot escape the certificate
|
||||
directory by using path separators. Keep the entire directory tree private as well.
|
||||
Keys and certificate name coverage are validated before publication. Generated
|
||||
self-signed certificates are development material, not automatic public trust.
|
||||
|
||||
Existing TLS sessions/tunnels are not revoked by changing a certificate or ACL.
|
||||
Policies apply to new requests and handshakes. Restart/stop the relevant process for
|
||||
immediate termination until a scoped administrative close operation is implemented.
|
||||
|
||||
WebSocket payloads remain opaque byte streams. The proxy validates upgrade metadata,
|
||||
not application-level authorization or message semantics. Frame/message limits on a
|
||||
backend remain the backend's responsibility. Proxy buffers, tunnel/connection counts
|
||||
and inactivity timers bound proxy-side resource usage.
|
||||
|
||||
## Information and resource controls
|
||||
|
||||
Access logging does not collect credential headers, query values, cookies, bodies
|
||||
or WebSocket payloads. Hostnames and paths are logged; never put secrets in them. Do not enable third-party verbose tracing or application logging without
|
||||
reviewing their output separately. Access rings, viewer slots, auth work, updates,
|
||||
DNS workers and request/connection admission are bounded. A slow log viewer does not
|
||||
create an unbounded delivery queue.
|
||||
|
||||
Backups include TLS private keys and credential/session state. Restore matching
|
||||
SQLite and certificate data together, then revoke restored sessions. Never commit
|
||||
`.env`, the data directory, backups or generated certificates to a public repository.
|
||||
|
||||
## Not a completed security feature
|
||||
|
||||
Docker socket access controls, service-account metrics access,
|
||||
2FA, roles, provider secret storage, certificate
|
||||
expiry automation, a full special-address registry policy and independent fuzz/load
|
||||
assessment remain roadmap work. Feature availability is not evidence of a completed
|
||||
security audit or a performance guarantee.
|
||||
|
||||
|
||||
## Cache, response transforms and ports (0.1.0)
|
||||
|
||||
Cache is enabled by default in 0.8.1 and ACLs precede lookup. Cookie (outside the
|
||||
configured static-asset exception), Authorization, Range, unsafe preconditions and
|
||||
request/response `no-store` remain hard shared-cache exclusions. Conditional validators
|
||||
can be satisfied from a fresh object or revalidated against the origin. Response
|
||||
`no-cache` with a usable validator may be retained only for mandatory validation before reuse. Origin privacy is
|
||||
checked before custom header removal, and generated request IDs are not cached. Bounded
|
||||
fill permits, object/entry/byte limits and generation checks protect cancellation,
|
||||
update and purge paths. Purge is authenticated, CSRF-protected and audited, not a
|
||||
public PURGE/BAN capability.
|
||||
|
||||
Compression is opt-in, with authenticated/private/no-transform exclusions. Response
|
||||
rules cannot overwrite protected framing and identity fields. Required Age remains
|
||||
on cache hits even when debug headers are disabled. Server hiding is cosmetic and
|
||||
must not be considered an access-control or vulnerability mitigation substitute.
|
||||
|
||||
Standard public 80/443 ports are supported without globally forbidding remote
|
||||
origins using those ports. Local listener targets remain guarded. Review SETTINGS.md
|
||||
for interface-enumeration and restart semantics. A Linux service can grant only
|
||||
CAP_NET_BIND_SERVICE to a dedicated unprivileged account; the application does not
|
||||
acquire capabilities itself. Public listener controls do not implicitly expose the separate admin
|
||||
API. The provided systemd unit is an unexecuted example, not an audit result.
|
||||
|
||||
Language packs are trusted build inputs with size/type/metadata bounds. The browser
|
||||
renders strings as text and falls back per key. Translations are not executable
|
||||
plugins, and no directory browsing or runtime arbitrary file loading is exposed.
|
||||
|
||||
## 0.2.0 frontend and pool boundaries
|
||||
|
||||
An explicit vhost binding is checked using the accepted stream's real local IP,
|
||||
port and TLS state. Host, SNI and forwarded headers cannot assert a different local
|
||||
address. A shared wildcard TCP listener does not grant every vhost access on every
|
||||
accepted IP. Legacy routing does not inherit additional frontend sockets. Conflicting
|
||||
hostname ownership is rejected, including disabled declarations.
|
||||
|
||||
Binding a private IP is not an authorization mechanism or firewall. NAT, port
|
||||
forwarding or another proxy can make that destination reachable. Configure network
|
||||
restrictions and application authentication as well; no trusted-proxy identity or
|
||||
Keepalived/VRRP service is introduced. New unavailable IP bindings fail startup.
|
||||
|
||||
Health probes share literal/DNS/allowlist/loop protections, including actual old
|
||||
listeners and desired new listeners, and cannot follow redirects to arbitrary
|
||||
origins. They are bounded and do not use user cookies or credentials. Probes can
|
||||
still hit an operator-selected GET path; select a side-effect-free health endpoint.
|
||||
|
||||
Affinity uses opaque random tokens but is not authentication, CSRF protection or
|
||||
session replication. Tokens survive compatible edits, not process restarts. Cookie
|
||||
mode bypasses cache; the dedicated cookie is stripped before origin forwarding and
|
||||
cannot be overridden by an origin Set-Cookie. No failed request, especially a write,
|
||||
is replayed on another member to obtain a successful response.
|
||||
|
||||
Dedicated per-vhost security headers also cover matching-host denials/errors and
|
||||
cache hits. HSTS is removed on plaintext; includeSubDomains/preload remain explicit
|
||||
opt-ins. Preload directives do not enroll a domain in a browser list. Arbitrary CSP
|
||||
and Permissions-Policy values are encoding-validated, not semantically audited.
|
||||
Old configurations retain origin headers unless an explicit policy overrides them.
|
||||
|
||||
## Certificate uploads and custom pages (0.3.0)
|
||||
|
||||
Certificate upload is an authenticated local-control-plane mutation protected by
|
||||
Origin and CSRF validation, body/per-file bounds and two-worker admission. PEM pairs
|
||||
are parsed, key-matched and checked against supplied DNS names. Private immutable
|
||||
files use generated simple names, mode 600 and the existing no-symlink/directory
|
||||
lock protections. Public API responses/config/audit contain metadata, not key PEM.
|
||||
JavaScript clears file controls after use, but does not claim secure erasure of
|
||||
browser memory. Only configuration publication activates an inventory selection.
|
||||
No new listener or public certificate-upload endpoint is created.
|
||||
|
||||
Custom HTML is fully trusted administrator-authored content served on the chosen
|
||||
public vhost. It may contain executable HTML/scripts there; it is never previewed
|
||||
or inserted as HTML in the admin DOM. Do not upload untrusted markup. The fixed
|
||||
welcome page interpolates only the software version, not Host, URL or user input.
|
||||
HTML is bounded to 32 KiB per page and by the overall 256 KiB configuration limit.
|
||||
Responses use no-store; old representation encoding/length/cookies are discarded
|
||||
when replacing an origin error. Authentication challenges, Allow and Retry-After
|
||||
are retained, then administrator response/security rules are applied.
|
||||
|
||||
ACLs run before static/fallback/direct-IP pages. Even a custom status 200 for a
|
||||
blocked request never authorizes an upstream fetch. Such overrides can confuse
|
||||
clients and monitoring; retaining the original 401/403/5xx status is recommended.
|
||||
Direct-IP HTTPS still needs a completed TLS handshake and a suitable certificate;
|
||||
an HTTP welcome page cannot remove a TLS certificate-name error.
|
||||
|
||||
## Integration boundaries in 0.4.0
|
||||
|
||||
Tinyauth runs after host/path ACLs and before any cached/static/origin response or
|
||||
WebSocket upgrade. Incoming identity headers are stripped, including after generic
|
||||
header rules, and only configured fields from a successful verifier are copied.
|
||||
The verifier gets no request body or admin session cookie. Its DNS/private-network
|
||||
and TLS checks match the origin safety boundary. Authentication failure cannot be
|
||||
turned into a 200 by custom pages. Denials and protected responses are no-store;
|
||||
there is no auth-result or protected-content shared cache. Existing upgraded
|
||||
sessions are not reauthenticated continuously.
|
||||
|
||||
Only configured login-origin redirects are accepted. Do not expose the fake-auth
|
||||
helper or treat its test cookie as an actual login. H3 uses the same routing,
|
||||
auth, request limits and response policies; 0-RTT is disabled. Transport resource
|
||||
limits do not replace rate limiting, firewalls or independent security/conformance
|
||||
testing. H3 is uncompiled/unexecuted in this packaging environment.
|
||||
|
||||
Diagnostic response fields are hidden by default, but origin secrets still need
|
||||
explicit response rules. In 0.5.0 the dedicated controls expose request ID and
|
||||
revision independently; the obsolete hide_mock_origin field is not accepted. X-Mock-Origin can be
|
||||
removed using ordinary response-header rules. Scope labels on listeners never
|
||||
enforce network restrictions. See ACME_RFC2136.md for private TSIG/account storage
|
||||
and the separate backup requirement for manual DNS-01 issuance.
|
||||
Reference in new issue
Block a user