Sitelet https://github.com/EroyEroy/code-duck/security
Skip to content

Security: EroyEroy/code-duck

Security

SECURITY.md

Security

CodeDuck installs a global keyboard hook — mechanically the same thing a keylogger installs. That is not a detail to bury, so this document states what the hook does, what it cannot do, and how to report it when you find something that contradicts either.

Supported versions

Version Supported
1.0.x yes
< 1.0 no

Only the latest release gets fixes. There is no LTS branch.

Reporting a vulnerability

Do not open a public issue for a security problem. Use GitHub's private vulnerability reporting instead:

Report a vulnerability →

That opens a private thread visible only to the maintainers. Expect a first response within 7 days. If a report is confirmed, the fix ships in a patch release and the advisory is published once the release is out.

This is a hobby project maintained by one person — there is no bounty, and no paid support. What you get is an honest answer and a fix.

What is in scope

Anything that breaks the guarantees below is a vulnerability, not a bug:

  • Any path by which a raw keycode, character, or per-key timing escapes src/main/input/classifier.ts — over IPC, to disk, or into a log.
  • Any path by which the cursor position (rather than a direction) reaches the renderer or the disk.
  • Any network call at all. The app makes none by design.
  • Renderer sandbox escapes, contextIsolation bypasses, or anything that lets page content reach Node APIs.
  • Tampering with the installer or the release artifacts.

What is not in scope

  • SmartScreen and antivirus warnings. The build is unsigned; see below.
  • The existence of the keyboard hook. It is the feature. How it is constrained is in scope; that it exists is not.
  • An attacker who already has code execution or admin rights on the machine. They do not need this app.

The guarantees

These are enforced by tests and by the build, not just promised in prose:

  • The raw keycode lives for exactly one function call. classifier.ts is the only module that ever sees one. It returns one of five coarse categories — type, newline, delete, nav, modifier — and the keycode dies there. classifier.test.ts sweeps every one of the 65536 possible keycodes and asserts the output is always one of those five. Another test replays a real hook recording of someone typing "hello duck" and asserts the ten letters collapse into ten indistinguishable values.
  • Nothing about your input is stored. Anywhere. Not to disk, not in memory beyond a second or so. The only thing this app persists is where you dragged the duck to.
  • The pointer sends a direction, never a position. The renderer aims the pupils without ever learning where your mouse is.
  • No network calls of any kind. No telemetry, no update check, no analytics. The overlay's CSP blocks remote origins outright.
  • src/shared/ cannot reach a filesystem or a socket. ESLint forbids it from importing Electron or Node, and it is typechecked twice — once with no DOM lib, once with no Node types — so platform APIs are a compile error there.

If you find a way to make any of the above false, that is exactly the report this document is asking for.

Verifying what you run

The releases are unsigned. SmartScreen will warn on first run, and some antivirus heuristics will flag the global hook — that is the honest cost of the feature, and a code-signing certificate is out of scope for now.

Since a signature cannot vouch for the binary, the source can. Every release is built by .github/workflows/release.yml on a GitHub-hosted Windows runner, from the tagged commit, with no human touching the artifact in between — the build log is public and shows exactly what went in.

If you would rather not trust that either, build it yourself:

corepack enable
pnpm install
pnpm build
pnpm exec electron-builder --win

An app that reads your keyboard should have to earn its trust. Read src/main/input/, it is small on purpose.

There aren't any published security advisories