Skip to content

← Public intelligence

npm package

@actual-app/sync-server

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

8 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. High, CVSS 7.1npmAmendedPublished

    Actual Sync Server: CORS Proxy GitHub API Allowlist Prefix Bypass Leaks Private Repositories Through the Server GitHub Token

    CVE-2026-57449 · GHSA-m62c-5q34-f3cf

    Affected
    • npm @actual-app/sync-server <= 26.6.0
    Fixed in
    26.7.0· Vendor fix available
    Issue
    Actual Sync Server's CORS proxy is intended to let authenticated users fetch resources only from repositories listed in the official plugin allowlist. When ACTUALGITHUBTOKEN is configured, the proxy automatically attaches the server's GitHub token to GitHub requests. The GitHub API allowlist check uses a raw startsWith() prefix test for /repos/{owner}/{repo} without requiring a path boundary after the repository name. If an allowlisted public plugin repository is https://github.com/acme/plugin, the proxy also accepts GitHub API URLs such as: Those URLs are outside the allowlisted repository but still pass because their API path starts with /repos/acme/plugin. The proxy then forwards the request with the server's ACTUALGITHUBTOKEN, allowing any authenticated Actual user to read private GitHub resources reachable by that token. Affected Endpoint - GET /cors-proxy?url=... This endpoint is mounted only when: Source: packages/sync-server/src/app.ts:68-70 Details The CORS proxy is…

    Recommended action: Upgrade to 26.7.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  2. High, CVSS 8.3npmAmendedPublished

    @actual-app/sync-server: Disabled OpenID users keep access through existing session tokens

    CVE-2026-49229 · GHSA-cq9c-6w48-qmfg

    Affected
    • npm @actual-app/sync-server <= 26.5.2
    Fixed in
    26.6.0· Vendor fix available
    Issue
    In OpenID multi-user mode, disabling a user only blocks future OpenID login for that identity. Existing Actual session tokens for the disabled user remain valid, so the user can continue calling authenticated server endpoints after an administrator has disabled the account. Details The disabled-user check is present during OpenID login finalization. Existing users are only accepted when the matching row has enabled = 1, and a disabled row causes the OpenID grant to fail before a new session token is created. The shared session validation path does not perform the same enabled-user check. It accepts any existing token row that has not expired, then returns the session object to every route protected by validateSessionMiddleware. This means account disablement and session authorization diverge: The default token expiration setting is never, so this is not just a short race after disablement on default deployments. Admins can change a user's enabled state through the user update…

    Recommended action: Upgrade to 26.6.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  3. Medium, CVSS 4.3npmAmendedPublished

    @actual-app/sync-server's missing authorization on GET /secret/:name allows non-admin OpenID users to enumerate admin-configured bank-sync secrets

    CVE-2026-46700 · GHSA-3f62-qv96-4p78

    Affected
    • npm @actual-app/sync-server < 26.6.0
    Fixed in
    26.6.0· Vendor fix available
    Issue
    In @actual-app/sync-server, the GET /secret/:name endpoint (app-secrets.js:53) checks only that the caller has a valid session — it does not verify the caller is an admin. The sibling POST /secret/ handler does enforce an admin check in OpenID mode, exposing an authorization asymmetry. Any authenticated non-admin (BASIC) user in OpenID multi-user deployments can probe the secrets store and learn which admin-managed bank-sync integrations have been configured (existence, not values). This includes integration credentials that are not otherwise observable to non-admins, such as simplefinaccessKey, pluggyaiclientSecret, pluggyaiitemIds, and the gocardless secrets. Details packages/sync-server/src/app-secrets.js mounts validateSessionMiddleware at the router level (line 15), so all handlers inherit only "must be authenticated." The POST handler then explicitly upgrades to an admin check when the active auth method is openid: The sibling GET handler skips both the method check and…

    Recommended action: Upgrade to 26.6.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  4. High, CVSS 8.8npmAmendedPublished

    Actual has Privilege Escalation via 'change-password' Endpoint on OpenID-Migrated Servers

    CVE-2026-33318 · GHSA-prp4-2f49-fcgp

    Affected
    • npm @actual-app/sync-server < 26.4.0
    Fixed in
    26.4.0· Vendor fix available
    Issue
    Any authenticated user (including BASIC role) can escalate to ADMIN on servers migrated from password authentication to OpenID Connect. Three weaknesses combine: POST /account/change-password has no authorization check, allowing any session to overwrite the password hash; the inactive password auth row is never removed on migration; and the login endpoint accepts a client-supplied loginMethod that bypasses the server's active auth configuration. Together these allow an attacker to set a known password and authenticate as the anonymous admin account created during the multiuser migration. --- Details packages/sync-server/src/app-account.js:120-132 — the /account/change-password route validates only that a session exists. No admin role check is performed packages/sync-server/src/accounts/password.js:113-125 — changePassword() updates the hash with no current-password confirmation: packages/sync-server/src/accounts/password.js:56-62 — loginWithPassword() always authenticates as…

    Recommended action: Upgrade to 26.4.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  5. Medium, CVSS 5.3npmAmendedPublished

    Actual Sync Server has an Authenticated Path Traversal

    CVE-2026-3089 · GHSA-27vg-33gh-4hwg

    Affected
    • npm @actual-app/sync-server <= 26.2.0
    Fixed in
    26.3.0· Vendor fix available
    Issue
    Actual Sync Server allows authenticated users to upload files through POST /sync/upload-user-file. In versions prior to 26.3.0, improper validation of the user-controlled x-actual-file-id header means that traversal segments (../) can escape the intended directory and write files outside userFiles. Mitigations The vulnerability can be mitigated in prior versions by running the sync server in a filesystem sandbox.

    Recommended action: Upgrade to 26.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  6. Medium, CVSS 5.7npmAmendedPublished

    @actual-app/sync-server: Missing authorization in sync endpoints allows cross-user budget file access in multi-user mode

    CVE-2026-27638 · GHSA-qmjj-p7m9-wjrv

    Affected
    • npm @actual-app/sync-server <= 26.2.0
    Fixed in
    26.2.1· Vendor fix available
    Issue
    In multi-user mode (OpenID), the sync API endpoints (/sync/) don't verify that the authenticated user owns or has access to the file being operated on. Any authenticated user can read, modify, and overwrite any other user's budget files by providing their file ID. Affected Code File: packages/sync-server/src/app-sync.ts The validateSessionMiddleware on line 31 confirms the user is authenticated, but individual endpoints only check that the file exists (via verifyFileExists), never that the requesting user owns or has access to the file. Compare with POST /sync/delete-user-file (lines 394-430) which correctly checks: This check is missing from all other endpoints. Affected Endpoints - GET /sync/download-user-file - download any budget file - POST /sync/upload-user-file - overwrite any budget file - POST /sync/sync - read/write sync messages of any file - POST /sync/user-get-key - read encryption key info - POST /sync/user-create-key - change encryption key - POST /sync/reset-user-file…

    Recommended action: Upgrade to 26.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →
  7. Critical, CVSS 9.2npmAmendedPublished

    ActualBudget server is Missing Authentication for SimpleFIN and Pluggy AI bank sync endpoints

    CVE-2026-27584 · GHSA-m2cq-xjgm-f668

    Affected
    • npm @actual-app/sync-server < 26.2.1
    Fixed in
    26.2.1· Vendor fix available
    Issue
    Missing authentication middleware in the ActualBudget server component allows any unauthenticated user to query the SimpleFIN and Pluggy.ai integration endpoints and read sensitive bank account balance and transaction information. Impact This vulnerability allows an unauthenticated attacker to read the bank account balance and transaction history of ActualBudget users. This vulnerability impacts all ActualBudget Server users with the SimpleFIN or Pluggy.ai integrations configured. The ActualBudget Server instance must be reachable over the network. Details The ActualBudget server component allows for integration with SimpleFIN and Pluggy.ai services. These services read bank account balances and transaction data from users' banks and return the data to ActualBudget. The affected endpoints facilitate this integration and are intended to be used only by logged in users for the purposes of syncing bank transaction data. The vulnerable source code is in the following files in the…

    Recommended action: Upgrade to 26.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.com (1)osv.dev (2)Source checked Evidence →
  8. Medium, CVSS 4.2npmAmendedPublished

    Actual Sync-server Gocardless service is logging sensitive data including bearer tokens and account numbers

    GHSA-xvp7-8vm8-xfxx

    Affected
    • npm @actual-app/sync-server <= 25.10.0
    Fixed in
    25.11.0· Vendor fix available
    Issue
    The GoCardless components in Actualbudget in are logging responses to STDOUT in a parsed format using console.logand console.debug (Which in this version of node is an alias for console.log). This is exposing sensitive information in log files including, but not limited to: - Gocardless bearer tokens. - Account IBAN and Bank Account numbers. - PII of the account holder. - Transaction details (Payee bank information, Recipient account numbers, Transaction IDs)... Details Whenever GoCardless responds to a request, the payload is printed to the debug log: https://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/banks/integration-bank.js#L25-L27 This in turn logs the following information to Docker (all values removed here. These fields are possibly dependent on what is returned by each institution so may differ):…

    Recommended action: Upgrade to 25.11.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:osv.dev (1)github.com (2)Source checked Evidence →