Quick Take
- What: CVE-2026-125749, an insecure direct object reference (IDOR) vulnerability in TaxHacker through version 0.8.5, allows authenticated users to modify or delete other users’ categories, projects, custom fields, and currencies.
- Who is affected: Multi-user TaxHacker deployments (SELF_HOSTED_MODE=false). Single-user self-hosted instances are not affected.
- What to do: Update to a version containing commit d84a912 or later. The fix was merged on November 10, 2026.
- Severity: Medium (CVSS 4.2). Requires authentication and knowledge of the victim’s UUID.
- Status: Patch available as of November 10, 2026.
In plain English
TaxHacker is a self-hosted accounting app that uses AI to categorize expenses. A security flaw in versions up to 0.8.5 let one logged-in user mess with another user’s accounting setup. If an attacker knew your user ID (a long random code), they could delete your expense categories, change your project settings, or wipe out how your transactions were organized. This only affects installations that allow multiple users to sign up.
What you should do: If you run a multi-user instance, update to the latest version from GitHub.
What happened
Security researcher hieuPenguinnn discovered that twelve Server Actions in TaxHacker’s settings module accepted a userId parameter directly from the client without verifying it matched the authenticated session. The vulnerable functions are in app/(app)/settings/actions.ts and include addProjectAction, editProjectAction, deleteProjectAction, addCurrencyAction, editCurrencyAction, deleteCurrencyAction, addCategoryAction, editCategoryAction, deleteCategoryAction, addFieldAction, editFieldAction, and deleteFieldAction.
Every other Server Action in the TaxHacker codebase calls getCurrentUser() to resolve the acting user from the session and then uses user.id. The settings CRUD actions instead took userId as their first argument and passed it straight to the model layer. Because Next.js Server Actions exported from a “use server module are directly invocable RPC endpoints, an authenticated attacker could call, for example, deleteCategoryAction(victim-user-id”, “office”) to delete another user’s category and null the categoryCode on that user’s transactions.
The middleware in proxy.ts only checks that a session cookie is present on a fixed list of path prefixes. It does not verify that the userId in the action call matches the authenticated user. The model functions in models/categories.ts, models/projects.ts, models/fields.ts, and models/currencies.ts correctly scope their queries to the userId they receive, but they trust the value passed in.
The vulnerability was reported on November 5, 2026, in GitHub issue #204. The maintainer vas3k closed the issue on November 10, 2026, with a fix in commit d84a912f3a06b141cc275bb07115a204e7f10128. The fix removes the userId parameter from all twelve actions and instead calls getCurrentUser() inside each function, matching the pattern used everywhere else in the codebase.
What you should do
If you run a multi-user TaxHacker instance (SELF_HOSTED_MODE=false), update to a version that includes commit d84a912 or later. The project does not use semantic versioning for every commit, so pull the latest code from the main branch on GitHub. If you run TaxHacker in single-user mode (the default for self-hosted deployments), you are not affected and no action is required.
What it means
This vulnerability is a textbook example of CWE-639 (Authorization Bypass Through User-Controlled Key) and CWE-862 (Missing Authorization). The impact is limited to integrity and availability of another user’s accounting configuration and transaction classification. An attacker cannot read another user’s documents or transaction details through this flaw, only corrupt or delete their categories, projects, custom fields, and currencies. The attacker must be authenticated and must know the victim’s userId, which is a random UUID not enumerable from these endpoints. The CVSS score of 4.2 reflects the need for authentication and prior knowledge of the victim’s identifier.



