{"answers":{"affected":"2 open source packages ship an affected version, including @actual-app/sync-server.","exploited":"There is no known exploitation of GHSA-xvp7-8vm8-xfxx in the wild and no public exploit code.","fix":"Upgrade @actual-app/sync-server to 25.11.0 or later.","what":"GHSA-xvp7-8vm8-xfxx is a vulnerability in @actual-app/sync-server, published on 20 Oct 2025. An attacker can exploit it over the internet without logging in, with no action from the victim."},"fix_prompt":"Check this codebase for GHSA-xvp7-8vm8-xfxx and fix it if it is affected.\n\nWhat it is: GHSA-xvp7-8vm8-xfxx is a vulnerability in @actual-app/sync-server, published on 20 Oct 2025. An attacker can exploit it over the internet without logging in, with no action from the victim.\nExploitation: There is no known exploitation of GHSA-xvp7-8vm8-xfxx in the wild and no public exploit code.\n\nAffected packages and fixed versions:\n- @actual-app/sync-server (npm): affected all versions; fixed in 25.11.0\n- @actual-app/sync-server (npm): affected all versions; fixed in 25.11.0\n\nTask:\n1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.\n2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.\n3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.\n4. Run the tests and summarise what changed and why.\n5. If nothing in the project is affected, say so and change nothing.\n\nReference: https://insights.sbomify.com/GHSA-xvp7-8vm8-xfxx/ (Markdown: https://insights.sbomify.com/GHSA-xvp7-8vm8-xfxx/index.md)","id":"GHSA-xvp7-8vm8-xfxx","markdown":"https://insights.sbomify.com/GHSA-xvp7-8vm8-xfxx/index.md","name":"GHSA-xvp7-8vm8-xfxx","record":{"aliases":[],"analysis":{"component_type":"server_software","fix_type":"patch","impacts":["data_read"],"network_reachable":"yes","non_default_config":false,"product_category":"Actual Budget sync server","requires_auth":"none","summary":"The Actual Budget sync server logs sensitive banking data, including bearer tokens and account numbers, to standard output, exposing PII and financial details.","user_interaction":"not_required","vuln_class":"information_disclosure"},"analysis_generated_by":"qwen3.8-flash-next","assigner":null,"cpe":[],"cvss":{"score":null,"severity":null,"source":null,"vector":null,"version":null},"cwes":[],"description":"### Summary\nThe GoCardless components in Actualbudget in are logging responses to STDOUT in a parsed format using `console.log`and `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:\n\n- Gocardless bearer tokens.\n- Account IBAN and Bank Account numbers.\n- PII of the account holder.\n- Transaction details (Payee bank information, Recipient account numbers, Transaction IDs)...\n\n### Details\n\nWhenever GoCardless responds to a request, the payload is printed to the debug log: \nhttps://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/banks/integration-bank.js#L25-L27\n\nThis 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):\n\n```json\n{\n  \"account\": {\n    \"resourceId\": \"\",\n    \"iban\": \"\",\n    \"bban\": \"\",\n    \"currency\": \"\",\n    \"name\": \"\u003cfull legal name in the bank\u003e\",\n    \"product\": \"\",\n    \"status\": \"\",\n    \"bic\": \"\",\n    \"usage\": \"\",\n    \"id\": \"\",\n    \"created\": \"\",\n    \"last_accessed\": \"\",\n    \"institution_id\": \"\",\n    \"owner_name\": \"\",\n    \"institution\": {\n      \"id\": \"\",\n      \"name\": \"\",\n      \"bic\": \"\",\n      \"transaction_total_days\": \"\",\n      \"countries\": [\n        \"\"\n      ],\n      \"logo\": \"\",\n      \"max_access_valid_for_days\": \"\",\n      \"supported_features\": [\n        \"\",\n        \"\",\n        \"\"\n      ],\n      \"identification_codes\": []\n    }\n  }\n}\n```\n\nhttps://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/banks/integration-bank.js#L83-L85\n\nThis is the first of the 10 transactions:\n```json\n{\n  \"top10Transactions\": [{\n    \"transactionId\": \"\",\n    \"entryReference\": \"\",\n    \"bookingDate\": \"\",\n    \"valueDate\": \"\",\n    \"transactionAmount\": {\n      \"amount\": \"\",\n      \"currency\": \"\"\n    },\n    \"creditorName\": \"\",\n    \"creditorAccount\": {\n      \"bban\": \"\"\n    },\n    \"debtorName\": \"\",\n    \"debtorAccount\": {\n      \"bban\": \"\"\n    },\n    \"remittanceInformationUnstructured\": \"\",\n    \"remittanceInformationStructuredArray\": [\n      {\"reference\": \"\", \"referenceType\": \"\"}\n    ],\n    \"additionalInformation\": \"\",\n    \"proprietaryBankTransactionCode\": \"\",\n    \"debtorAgent\": \"\",\n    \"internalTransactionId\": \"\",\n    \"payeeName\": \"\",\n    \"date\": \"\"\n  }]\n}\n```\n\nAdditionally, in the error handling for GoCardless, there is a catch all for unclassified errors that prints the entire stack trace to the console.\n\nhttps://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/app-gocardless.js#L263-L264\n\nOur bank was offline today for maintenance which threw a 503 error from Gocardless. The entire response payload was dumped to console, which includes the Bearer tokens for accessing GoCardless:\n\n```java\nSomething went wrong ServiceError: Institution service unavailable\n    at handleGoCardlessError (file:///app/src/app-gocardless/services/gocardless-service.js:59:13)\n    at Object.getTransactions (file:///app/src/app-gocardless/services/gocardless-service.js:530:7)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at async Object.getNormalizedTransactions (file:///app/src/app-gocardless/services/gocardless-service.js:267:26)\n    at async file:///app/src/app-gocardless/app-gocardless.js:186:13 {\n  details: h [AxiosError]: Request failed with status code 503\n      at te (file:///app/node_modules/nordigen-node/dist/index.esm.js:13:914)\n      at IncomingMessage.\u003canonymous\u003e (file:///app/node_modules/nordigen-node/dist/index.esm.js:17:16315)\n      at IncomingMessage.emit (node:events:529:35)\n      at endReadableNT (node:internal/streams/readable:1400:12)\n      at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {\n    code: 'ERR_BAD_RESPONSE',\n    config: {\n      transitional: {\n        silentJSONParsing: true,\n        forcedJSONParsing: true,\n        clarifyTimeoutError: false\n      },\n      adapter: [ 'xhr', 'http' ],\n      transformRequest: [ [Function (anonymous)] ],\n      transformResponse: [ [Function (anonymous)] ],\n      timeout: 0,\n      xsrfCookieName: 'XSRF-TOKEN',\n      xsrfHeaderName: 'X-XSRF-TOKEN',\n      maxContentLength: -1,\n      maxBodyLength: -1,\n      env: {\n        FormData: [Function: _] {\n          LINE_BREAK: '\\r\\n',\n          DEFAULT_CONTENT_TYPE: 'application/octet-stream'\n        },\n        Blob: [class Blob]\n      },\n      validateStatus: [Function: validateStatus],\n      headers: T [AxiosHeaders] {\n        Accept: 'application/json',\n        'Content-Type': 'application/json',\n        'User-Agent': 'Nordigen-Node-v2',\n        'Authorization': 'Bearer eyJ0eXAi... (the full token is in the response)',\n        'Accept-Encoding': 'gzip, compress, deflate, br'\n      },\n      method: 'get',\n      url: URL {\n        href: 'https://bankaccountdata.gocardless.com/api/v2/accounts/\u003cAccount id Was Here\u003e?date_from=2024-12-22',\n        origin: 'https://bankaccountdata.gocardless.com',\n        protocol: 'https:',\n        username: '',\n        password: '',\n        host: 'bankaccountdata.gocardless.com',\n        hostname: 'bankaccountdata.gocardless.com',\n        port: '',\n        pathname: '/api/v2/accounts/\u003cAccount id Was Here\u003e/transactions',\n        search: '?date_from=2024-12-22',\n        searchParams: URLSearchParams { 'date_from' =\u003e '2024-12-22' },\n        hash: ''\n      },\n      data: undefined\n    },\n```\nAnd quite a few pages more.\n\n### PoC\n- Setup an Actualbudget server inside of Docker. In this instance I was using the Docker Compose script posted in the repository: https://github.com/actualbudget/actual/blob/master/packages/sync-server/docker-compose.yml\n- Link a gocardless account to Actualbudget and sync a bank account\n- Observe in the container using `docker logs actual-actual_server-1 -f`  that sensitive details are logged to the console and ingested by docker. \n\n### Impact\nInformation disclosure. The services are available both on-premises and in environments that are not under the control of the end user, such as third-party providers who offer this application as a managed solution.","ecosystems":["npm"],"exploits":{"exploitdb":null,"first_seen":null,"github_poc":null,"max_poc_stars":null,"metasploit":null,"nuclei":null,"refs":[],"tier":null},"has_fix":true,"headline":"Actual Sync-server Gocardless service is logging sensitive data including bearer tokens and account numbers","id":"GHSA-xvp7-8vm8-xfxx","indexable":true,"kev":null,"kind":"advisory","links":{"ecosystem":"npm","product":null,"products":[],"type":"information_disclosure","year":"2025"},"n_packages":2,"n_references":null,"packages":[{"ecosystem":"npm","fixed":["25.11.0"],"introduced":["0"],"last_affected":[],"package":"@actual-app/sync-server","purl":null,"source":"GHSA-xvp7-8vm8-xfxx"},{"ecosystem":"npm","fixed":["25.11.0"],"introduced":["0"],"last_affected":[],"package":"@actual-app/sync-server","purl":"pkg:npm/%40actual-app/sync-server","source":"GHSA-xvp7-8vm8-xfxx"}],"products":null,"published":"2025-10-20","related":[],"sources":[{"class":"attribution","licence":"CC BY 4.0","name":"GitHub Advisory Database","prefix":"GHSA"}],"ssvc":{"automatable":null,"exploitation":null,"technical_impact":null},"state":null,"updated":null,"vendors":null},"summary":"The Actual Budget sync server logs sensitive banking data, including bearer tokens and account numbers, to standard output, exposing PII and financial details.","url":"https://insights.sbomify.com/GHSA-xvp7-8vm8-xfxx/"}