Skip to content

Security: hongnoul/hwatu

Security

SECURITY.md

Security policy

Threat model

hwatu is a local browser daemon for trusted local operators and trusted local automation. The hwatud daemon owns WebKitGTK browser windows and normally listens on a Unix-domain socket resolved by the hwatu-ipc crate under the current user's runtime directory. An optional bearer-authenticated TCP listener binds loopback only and is intended for an SSH tunnel. Neither transport is an Internet-facing API or an authorization boundary between mutually distrusting processes running as the same user.

Treat any process that can connect to the hwatu socket as able to drive the browser session. By default that includes opening pages, clicking, typing, reading page state, taking screenshots, and running page JavaScript through eval-capable automation. The human can see the same live session the agent drives, including authenticated pages and cookies.

Loopback TCP transport

TCP is disabled unless hwatud receives --listen and a token through --token-file, HWATU_TOKEN_FILE, or HWATU_TOKEN. Prefer a private token file over an environment variable so the secret does not enter shell history or process environments. Token files must be regular files inaccessible to group and other users, and tokens must contain at least 32 bytes. The daemon removes token environment variables before WebKit child processes start.

The listener rejects non-loopback addresses. Keep it behind an SSH tunnel and do not use port forwarding that exposes the client-side port to another host. Bearer authentication grants the complete browser-control capability described above; use a dedicated random token, copy it only through a secure channel, and rotate it if disclosure is possible. Authentication has a short deadline, wire frames and connection counts are bounded, and token comparison is constant-time. These controls reduce accidental exposure and resource abuse; they do not make the browser safe for untrusted remote clients.

Remote file inputs are transferred inline, staged in private daemon-owned files when WebKit needs a native file chooser, and deleted after their window no longer needs them. Returned artifacts are materialized on the client host. Inline payloads are bounded, and remote requests cannot select arbitrary paths on the daemon host.

Eval and prompt-injection risk

The default automation surface includes JavaScript evaluation:

  • CLI: hwatu eval ...
  • CLI one-shots: hwatu check --eval ... and hwatu render --eval ...
  • MCP: the eval tool and eval parameters embedded in check/render style tools
  • Raw IPC: Request::Eval, Request::Check { eval: ... }, and batches containing either

If an untrusted or prompt-injected agent reaches these tools while the daemon has authenticated browser state, it can execute same-origin JavaScript in pages the daemon loads. That may expose document.cookie when cookies are not HttpOnly, web storage, visible DOM content, CSRF-protected form state, and other page-accessible secrets. HttpOnly cookies are not readable via document.cookie, but authenticated actions may still be possible through normal browser requests.

Verification-job command execution

hwatu verify <spec.json> and the MCP verify_ui tool with spec_path can run optional preflight and server commands from that file. Commands use explicit argv arrays rather than a shell, but they still execute with the invoking user's permissions. Treat command-bearing verification specs as executable project configuration and review them before use.

MCP callers cannot place process commands in an inline spec. Inline specs containing preflight or server are rejected. They also cannot override cwd, artifacts_dir, or report_path, and their source paths and resolved symlinks must remain inside the MCP process working directory. Inline evidence uses a runtime-scoped Hwatu output directory. This prevents an unreviewed tool-call payload from directly creating a local process, selecting an arbitrary local output path, or hashing a file outside the workspace, but it does not make a referenced on-disk spec trustworthy.

Operator opt-outs

For authenticated sessions or untrusted agent workflows, start the daemon with eval disabled:

hwatud --no-eval

or set:

HWATUD_NO_EVAL=1 hwatud

This policy is enforced in the daemon before dispatch, so direct CLI, MCP, and raw socket requests receive the same rejection. It rejects direct eval, check/render requests with non-empty eval parameters, and batches containing eval surfaces.

To avoid persisting cookies, credentials, crash-recovery sessions, and discarded-window session blobs, start an ephemeral profile:

hwatud --ephemeral-profile

or set:

HWATUD_EPHEMERAL_PROFILE=1 hwatud

Ephemeral-profile mode uses WebKitGTK's memory-only ephemeral network session, disables persistent credential storage, skips persistent cookie setup, skips crash-session restore/save, and skips normal discarded-window state cleanup/writes. No temporary browser profile is created on disk.

For the strictest local handoff mode, combine both:

hwatud --no-eval --ephemeral-profile

Local-socket assumptions and limitations

  • hwatu does not sandbox, authenticate, or authorize same-user local clients that can reach the daemon socket.
  • File permissions and the operating system user boundary are the primary trust boundary.
  • A malicious same-user process may still drive non-eval automation such as clicks, typing, screenshots, downloads, or navigation.
  • --no-eval closes hwatu's explicit eval surfaces. It does not disable JavaScript that websites load themselves.
  • --ephemeral-profile avoids normal persistent browser/session/profile writes for the daemon. It does not make visited sites private from the network, the compositor, the kernel, or other same-user local observation.
  • Secrets visible in page pixels or DOM text may still be exposed by screenshot/snapshot tools even when eval is disabled.

Reporting security issues

Please report suspected vulnerabilities privately when possible. If GitHub private vulnerability reporting is enabled for this repository, use it. Otherwise contact the maintainer listed on the GitHub repository profile, or open a minimal public issue that describes the impact without publishing exploit details. Include your hwatu version, WebKitGTK version, operating system, session type, the daemon startup line, and whether --no-eval or --ephemeral-profile was in use.

There aren't any published security advisories