GHSA-xvp7-8vm8-xfxx: @actual app/sync server Actual Sync-server Gocardless Service Is Vulnerability
MODERATEGHSA-xvp7-8vm8-xfxx is a MODERATE (CVSS 4.2) actual sync-server gocardless service is vulnerability (CWE-209: Generation of Error Message Containing Sensitive Information) affecting @actual app/sync server libraries in the npm ecosystem. The issue involves actual sync-server gocardless service is logging sensitive data including bearer tokens and account numbers. Remediation is available by upgrading affected packages to version 25.11.0.
GHSA-xvp7-8vm8-xfxx at a Glance
Security Impact
CVSS: 4.2
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:H/UI:R/S:U/C:H/I:N/A:N).
How to Fix GHSA-xvp7-8vm8-xfxx
To remediate this vulnerability, upgrade all affected @actual app/sync server dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install @actual-app/sync-server@25.11.0
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls @actual-app/sync-server
How to Check if You Are Affected
To determine whether your Node.js application is affected by GHSA-xvp7-8vm8-xfxx, inspect your project dependencies using npm:
npm ls @actual-app/sync-server
Analyze the terminal output to locate any version of @actual app/sync server in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 25.11.0), your application is affected.
Note: The npm ls @actual-app/sync-server command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-209: Generation of Error Message Containing Sensitive Information, where the product generates an error message that includes sensitive information about its environment, users, or associated data. In @actual app/sync server, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
GHSA-xvp7-8vm8-xfxx Affected @actual app/sync server Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
@actual-app/sync-server
|
npm |
< 25.11.0
|
25.11.0
|
References
Frequently Asked Questions
What is GHSA-xvp7-8vm8-xfxx?
Which @actual app/sync server versions are affected?
What version fixes GHSA-xvp7-8vm8-xfxx?
Is @actual-app/sync-server affected?
What is the CVSS score of GHSA-xvp7-8vm8-xfxx?
What CWE is associated with GHSA-xvp7-8vm8-xfxx?
How can I check npm dependencies for GHSA-xvp7-8vm8-xfxx?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-xvp7-8vm8-xfxx",
"modified" : "2026-06-08T23:28:41Z",
"published" : "2025-10-20T17:55:59Z",
"aliases" : [ ],
"summary" : "Actual Sync-server Gocardless service is logging sensitive data including bearer tokens and account numbers",
"details" : "### 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\": \"<full legal name in the bank>\",\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.<anonymous> (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/<Account id Was Here>?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/<Account id Was Here>/transactions',\n search: '?date_from=2024-12-22',\n searchParams: URLSearchParams { 'date_from' => '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.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:L/AC:L/PR:H/UI:R/S:U/C:H/I:N/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "@actual-app/sync-server"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "25.11.0"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 25.10.0"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/actualbudget/actual/security/advisories/GHSA-xvp7-8vm8-xfxx"
}, {
"type" : "WEB",
"url" : "https://github.com/actualbudget/actual/commit/97482a082d502887ef22514b93e35e4c67f4f30f"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/actualbudget/actual"
}, {
"type" : "WEB",
"url" : "https://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/app-gocardless.js#L263-L264"
}, {
"type" : "WEB",
"url" : "https://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/banks/integration-bank.js#L25-L27"
}, {
"type" : "WEB",
"url" : "https://github.com/actualbudget/actual/blob/36c40d90d2fe09eb1f25a6e2f77f6dd40638b267/packages/sync-server/src/app-gocardless/banks/integration-bank.js#L83-L85"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-209", "CWE-215", "CWE-219" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2025-10-20T17:55:59Z",
"nvd_published_at" : null
}
}