Kaption is a desktop app that captures screen regions, calls out to a licensing backend, and locally decrypts translation packs. Security problems in any of those paths matter. This document describes how to report one.
For end-user safety information, current SHA-256 hashes, VirusTotal scans, and the source-code auditability overview, see kaption.one/security.
Email: security@kaption.one
Preferred contents:
- A clear description of the issue and the affected component (desktop, backend, landing, translation pipeline).
- Steps to reproduce, including the Kaption version (Settings → About → version, or
%APPDATA%\Kaption\app.log). - Your assessment of impact and severity.
- A proof-of-concept if one exists. Text, screenshots, screen recordings are all fine.
If you cannot use email, open a private security advisory on the GitHub repository instead (repo → Security → Report a vulnerability). Do not file a public issue, pull request, or Discord message for something you believe is exploitable.
- Initial acknowledgement: within 3 business days.
- Triage + severity assessment: within 7 business days.
- Fix target:
- Critical (remote code execution, licence bypass, decryption of other users' data): 14 days.
- High (auth bypass, account takeover, privilege escalation): 30 days.
- Medium: 60 days.
- Low / informational: shipped when convenient.
- Coordinated disclosure: we will work with you on a disclosure date. Default is 30 days after a fix ships, earlier if you prefer. Credit in release notes by your requested handle unless you ask otherwise.
In scope:
- The desktop client in this repository (C# 12 / .NET 10 WPF).
- The backend at
api.kaption.one(Cloudflare Worker, not in this repository). - The landing site at
kaption.one. - The translation pipeline that ingests Hoyoverse textmaps and ships encrypted
.gisub-distfiles over R2 (private; not in this repository).
Out of scope:
- Issues in third-party dependencies (PaddleOCR, ONNX Runtime, Cloudflare infrastructure, Velopack, log4net). Report those upstream; we will track and update.
- Social-engineering attacks against individual users.
- Denial-of-service that requires sustained attacker resources against our infrastructure (we handle infra at the Cloudflare layer).
- Missing security headers or TLS-configuration nits on marketing pages — welcome, but reported via GitHub issues is fine.
- Reports generated by automated scanners without a working proof-of-concept.
If you follow this policy in good faith, we will not pursue legal action, and we will work with you on disclosure. We consider the following explicitly allowed:
- Reverse-engineering the shipped Kaption binary to investigate a suspected issue.
- Creating throwaway accounts to test multi-device / concurrency behaviour (please tag them so we can clean them up).
- Reading our source code — it is published under the repo licence (see
../LICENSE) precisely so security researchers can audit it.
We ask that you do not:
- Exfiltrate or retain data belonging to real users.
- Disrupt the service for real users (load-test against your own accounts only).
- Run mass / automated scans against production endpoints.
These are not secrets; knowing them helps you report actionable issues:
- Session auth: HttpOnly JWT cookie, refreshed by the backend on every authenticated call.
- Device binding: separate device-activation JWT, issued per
device_idat activation time, revocable from the Dashboard. - Licence-tier enforcement: server-side effective-tier gate on every paid endpoint. Local-only gates are present for UX but are not relied on.
- File protection:
.gisubtranslation packs use AES-256-CBC for the bulk path and AES-CTR-with-per-block-HMAC for the mmap-friendly matcher blob. Both derive their AES + HMAC keys from a per-device 32-byte secret issued byPOST /api/app/file-protection-keyand persisted DPAPI-wrapped on the user's machine. There is no embedded application secret in the public source. If you find a decryption attack against a current-scheme file you recorded off your own machine, that is in scope. - Crash reporting: Sentry SDK pointing at a self-hosted GlitchTip instance. The DSN is empty in the public source; the released installer ships with a baked-in DSN. PII minimisation rules live in
CrashReportingService.cs.
- AES-256-CBC + HMAC-SHA256 (Encrypt-then-MAC) for
.gisubv2 (translation packs). - AES-256-CTR + HMAC-SHA256 per 4 KB block for
.gisubv3 (mmap-friendly matcher blob). - HMAC-SHA256 for LemonSqueezy webhook signature verification.
- PBKDF2-SHA256 (100,000 iterations, server-controllable within
[50,000, 500,000]) for key stretching. - RFC 7519 JWT for session and device tokens.
- DPAPI (CurrentUser scope) for at-rest activation blob and device-secret protection.
Issues with our use of these primitives — wrong mode, reused IV, weak salt, timing-leak comparison — are in scope.
If you prefer credit, we will list you in the release notes that ship the fix, optionally linking to a blog post / handle of your choice. If you prefer to stay anonymous, that is also fine.
Last updated: 2026-05-16.