Please open a private vulnerability report via GitHub's Security Advisories rather than a public issue. We will respond within 72 hours and aim to ship a fix within 14 days for confirmed high-severity issues.
If you can't use GitHub's UI, email
mcaney006@users.noreply.github.com
with [security] in the subject. Include:
- Affected version (
grok-insane --version) - Reproducer (smallest possible)
- Impact: data loss / RCE / privilege escalation / credential leak / DoS
- Whether you intend to disclose publicly and on what schedule
We do not currently run a bug bounty.
Every release is:
- Built with
SOURCE_DATE_EPOCHexported from the tip commit's authored timestamp (xtask ci --stage compute-source-date-epoch). This is a necessary, not sufficient, condition for byte-identical reproducibility — we do not currently re-build the artifact in CI and verify the hashes match. Thecargo xtask reproduciblecommand runs two clean builds locally andbail!s if they diverge; that is what we'd point at to verify the claim end-to-end. - Signed via Sigstore keyless (cosign) — verifiable against the public Rekor transparency log. SHA256SUMS is also signed so the file hashes themselves are anchored to the workflow's OIDC identity, not just trusted by virtue of sitting next to the binaries.
- Backed by a SLSA build-provenance attestation linking the artifact to the exact GitHub Actions run.
- Accompanied by a CycloneDX SBOM listing every transitive crate and version.
Verify:
cosign verify-blob \
--bundle <artifact>.cosign-bundle \
--certificate-identity-regexp 'https://github.com/mcaney006/grokmacos-better-version/.github/workflows/release\.yml@.*' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
<artifact>
gh attestation verify <artifact> --owner mcaney006
sha256sum -c SHA256SUMSSee docs/THREAT_MODEL.md for the full
analysis: assets, adversaries, and the specific control that mitigates
each risk class with file/line references.
- No unsafe code.
#![forbid(unsafe_code)]at the crate root. - Network:
https_only+ TLS 1.2 floor on every cloud provider; rustls (not OpenSSL); pre-first-byte timeout only on streaming endpoints; capped error-body read. - Auth headers (
Authorization: Bearer …,x-api-key, WebSocketAuthorization) are marked sensitive viaHeaderValue::set_sensitive(true), so HTTP-middleware loggers that honour the flag printSensitiveinstead of the raw token. - WebSocket: 10s connect timeout, 15s send timeout, 90s receive watchdog.
- Secrets: OS-keyring storage,
Zeroizingin-process, tracing filters that suppress framework-level log dumps. - Local provider host allowlist: the Local provider — the only
one allowed to send plain HTTP — refuses any host that isn't
loopback (127.0.0.0/8, ::1,
localhost). RFC 1918 / link-local /*.localare accepted only whenGROK_INSANE_ALLOW_LAN_LOCAL=1is set in the environment. Public-internet hosts are NEVER accepted from this provider. Seesrc/services/local.rsfor the enforcement. - SSE parse-failure logging: payload bytes are NOT logged at
WARN. We log payload length + a per-process keyed hash
fingerprint so log readers can correlate repeated failures of
the same event without disclosing user content. Raw payloads are
trace-only (
RUST_LOG=…=trace). - Storage: per-entry decode failures skipped with a log line — one corrupted row can never brick the app.
- CI/CD: least-privilege
permissions,persist-credentials: falseeverywhere, read-only release cache, template-injection-safe matrix passthrough, every action SHA-pinned.
Honest list. Treat every claim above as scoped to what its implementation actually does, not to what the word "secure" suggests.
- A compromised desktop session: the OS keyring, in-process memory, and any file the user can read are all reachable to malware running as that user. There is no anti-tamper / anti- debugging story, and adding one would be theatre.
- A locally-running malicious LLM: the Local provider host allowlist only prevents prompts from going to a public host. A hostile process listening on 127.0.0.1 (e.g. an attacker who can open a loopback socket) will receive prompts the user routes to it. Don't run untrusted code on the same machine.
- Process-memory leakage:
Zeroizing<String>clears the buffer on drop, but egui'sTextEditreallocates its backing buffer as the user types, and those old allocations are not tracked. A core dump or live debugger attached during key entry sees the key. - Side-channel timing: API key comparisons happen inside the provider, not in our code; we never branch on key bytes locally.
- A determined endpoint operator (any cloud LLM provider you point this at) can log your prompts. That is the provider's privacy policy, not a property of this client.
| Version | Supported |
|---|---|
| 0.1.x | ✅ |
| < 0.1 | ❌ |