* [AI] Reject invalid password inputs before hashing - Require non-empty strings at password validation, hashing and verification boundaries so JSON objects, arrays and other scalar types cannot reach Argon2's buffer conversion. - Add regressions for malformed passwords on fresh and configured servers, including assertions that rejected input never reaches Argon2. Advisory: https://github.com/actualbudget/actual/security/advisories/GHSA-3jjw-2hq7-mmm2 * [AI] Require admin permission for EnableBanking configuration - Require administrator permission to configure EnableBanking, even when credentials have not been configured yet. - Check permission before validating credentials with the provider or persisting secrets, and disable configuration controls for non-admins. - Test unauthenticated, BASIC and ADMIN requests against empty and existing configuration, preserving secrets and avoiding provider calls on denial. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-hfxx-qc34-gqcw * [AI] Neutralize BOM-prefixed CSV formulas - Detect spreadsheet formula triggers after leading BOM characters and prepend an apostrophe before the original text. - Protect textual CSV headers and scalar values as well as ordinary strings. - Preserve numeric output, including negative amounts, and cover repeated BOMs, formula triggers, quoting and Unicode text in regression tests. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-7jvc-qfpw-85g2 * [AI] Remove ambiguous Commerzbank payee matching - Split Commerzbank payees into non-empty whitespace/slash-delimited tokens and escape their literal text before constructing the cleanup expression. - Use consuming separators that cannot overlap the literal tokens, avoiding ambiguous matching on long runs of spaces or slashes. - Require separators between payee tokens: concatenated words in notes are no longer stripped. Allow 20 seconds for the hostile-case subprocess, including Node and Vite startup on slower CI runners. - Skip matching for empty payees while preserving normal note cleanup. - Exercise hostile payees, including the report's spaced-word reproducer, in a subprocess with a hard timeout; retain the existing bank fixtures. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-p34v-m2gp-w3jm * [AI] Reject unsafe IPv6 address classes in SSRF checks - Allow public unicast addresses by default. The private-network option additionally permits private, loopback, unique-local and carrier-grade NAT addresses. - Permit the well-known NAT64 prefix only for embedded public IPv4 destinations; private and metadata addresses remain blocked in both modes. - Reject other IPv6 transition, multicast, reserved and link-local classes in both modes, and classify IPv4-mapped addresses by the embedded IPv4 address. - Cover literal URLs, DNS answers, redirects and both SimpleFIN fetch paths, including NAT64, 6to4 and Teredo addresses, with synthetic upstreams. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-97j5-6g5r-42v5 * [AI] Exclude callback secrets from ordinary server logs - Log request method, pathname and response status without query strings, and restrict serialized metadata to the same safe fields. - Keep full OpenID and banking provider messages, response bodies, session identifiers and error stacks behind existing actual-sensitive namespaces. - Apply the same opt-in handling to shared banking errors, proxy target URLs and unhandled rejections; do not forward raw streaming errors to Express's ordinary error logger. - Stop logging stored secret values, including with debugging enabled. - Document targeted sensitive debugging and private support exchanges. - Test ordinary and opt-in output, query and serialized metadata leaks, provider failures, session URLs, streaming errors and secret storage. - Preserve provider format sequences by passing SimpleFIN response text as a debug format argument, rather than part of the format string. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-ppcp-hx2h-fm35 * [AI] Revoke password sessions when credentials change - Update the password hash and revoke all password-authenticated sessions in one transaction, including password changes through the local CLI. - Issue a fresh token for each successful password login instead of reusing an existing session token. - Recheck the verified password hash before creating a session so an in-flight login cannot restore access after a credential change. - Correct the UI's claim that other sessions remain signed in, and test multiple sessions, CLI resets, transaction rollback and login/reset races. This addresses session revocation and token reuse. Requiring the current password for remote changes is covered by the following commit. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-7363-3qq5-2frj https://github.com/actualbudget/actual/security/advisories/GHSA-4wgp-48c6-v9w3 * [AI] Require the current password for remote password changes - Require currentPassword alongside the replacement password for remote changes, preserving the administrator and password-authentication checks. - Verify the current credential, rate-limit attempts and reject a change if the verified password hash changes before the update. - Collect the current password in the client and handle failure to sign in after a successful change. Keep the local reset command available without the old password. - Test that a session token alone cannot change credentials and that failed requests preserve the existing password and sessions. - Clear the redundant success notice when signing in with the new password fails. Advisories: https://github.com/actualbudget/actual/security/advisories/GHSA-4wgp-48c6-v9w3 * [AI] Restrict Electron protocol launches and network file reveals - Allow only parsed HTTP/HTTPS URLs through external-opening IPC, new-window handling and navigation, addressing GHSA-7pf2-w24j-p6h2. - Also reject network/UNC paths in the separate file-reveal handler. A note such as [View receipt](//host/share/invoice.pdf) reaches showItemInFolder without passing through openExternal. On Windows, resolving that share can disclose NTLM authentication responses to an attacker-controlled server where network and authentication policies permit it. This additional flow was not demonstrated in the advisory. - Accept native absolute local paths without adding file-URL conversion. - Test protocol filtering and network-path rejection without invoking OS handlers. The note-to-file-reveal flow is code-confirmed; an actual Windows authentication exchange has not been reproduced. The following commit addresses the advisory's separate internal-origin classification finding. Advisory: https://github.com/actualbudget/actual/security/advisories/GHSA-7pf2-w24j-p6h2 Additional finding references: https://github.com/electron/electron/blob/v43.4.0/shell/common/platform_util_win.cc#L270-L340 https://learn.microsoft.com/en-us/windows-server/storage/file-server/smb-ntlm-blocking - Exercise Windows path semantics on all test platforms and exclude generated Electron tests and Vitest configuration from the packaged application. * [AI] Classify Electron app URLs exactly and block redirects - Replace substring checks with exact app://actual scheme/host matching and the existing development origin, http://localhost:3001. - Use the classification for browser handoffs and focus/log script execution so remote URLs containing app:// or localhost: are not mistaken for app pages. - Preserve the existing global renderer-navigation block and add redirect blocking there, without duplicating it in the main-window handlers. - Keep ordinary IPC registration unchanged; broad sender validation is outside this URL-classification fix. - Test misleading hosts, ports and URL substrings. Exercise ordinary clicks, new-window links and explicit browser IPC in Electron, asserting the exact HTTP/HTTPS URLs handed to the browser without opening real OS handlers. Exercise a local HTTP redirect to check the app stays put. Advisory: https://github.com/actualbudget/actual/security/advisories/GHSA-7pf2-w24j-p6h2 - Retain startup logs until an internal page finishes loading, then forward them to DevTools; cover startup delivery in the Electron navigation suite. * [AI] Choose import destinations from trusted local context - Allocate fresh local IDs for cloud downloads and local archive imports, ignoring destination IDs supplied in archived metadata. - Pass an explicit local destination for replacement downloads and verify its cloud-file association. Do not require matching sync group IDs, so downloading the reset version of the same cloud file remains possible. - Reject server metadata describing a different cloud file and close the budget before an authorized replacement. - Retain existing import metadata compatibility, collision error handling, nested archive layouts and backups; do not require a budget name. - Test targeted collisions, local recovery imports with obsolete IDs or missing optional metadata, mismatched cloud associations and replacement after a sync ID reset using real local files and databases. Advisory: https://github.com/actualbudget/actual/security/advisories/GHSA-7fr5-fjj8-hwjq - Reuse the matching local budget for API downloads after a sync reset, report cloud-file mismatches in API/CLI errors, and document local IDs. * [AI] Revoke sessions on sign-out and API shutdown Revoke only the supplied session on explicit sign-out. Clear local credentials if the server cannot be reached, and revoke password-created API sessions during shutdown without revoking caller-supplied tokens. Cover isolated and repeated revocation, invalid tokens, offline sign-out, borrowed API tokens and shutdown after a close failure. Session expiry policy is unchanged. Follow-up to: https://github.com/actualbudget/actual/security/advisories/GHSA-7363-3qq5-2frj
Actual Budget Community Documentation
This repo is the Actual Budget community documentation website, built using Docusaurus 3, a modern static website generator.
Docusaurus 3 uses Node.js, so if you are running Actual on your local machine, you should be able to easily run Docusaurus 3.
Welcome
Firstly, thank you for stopping by and giving up some of your time to either check out the documentation we have already produced or pick off some of the issues and help create some new documentation for our future users. Check out the guidelines for more information on how the documentation is structured and tips for consistent formatting.
Installation Methods
Actual Budget can be installed on many different platforms. However, at this time, the official Actual Budget documentation only supports the following methods:
- Local Installation (on your own machine)
- Actual-server
- Desktop apps
- Fly.io
- PikaPods
- Docker
If you would like to write documentation for another installation variant, please feel free to continue to do this and host it on your own personal blog, Medium, Tumblr, or any other short-form publication service. We will be more than happy to add a link to that from our documentation. Open a PR and add it to the list in the installation overview.
However, in doing so, you would become responsible for these instructions. If they become out of date or people want in-depth help with them, we will point them to you for assistance if the community is unable to help. If lots of people report issues with them, we may have to remove the link altogether.
Contributing
Please review the contributing documentation on our website: https://actualbudget.org/docs/contributing/
Issues
If you know of a part of Actual that isn't documented and you would like to know more about that part of the software, open an Issue and one of the documentation team will get to it. Or have a go at writing it yourself; we could really use all the help we can get.
Pull Requests
When submitting a pull request, please make sure that your contributions are complete. I am checking this repo regularly, so if I see an open PR, the likelihood of me pulling it and merging it is high.
Documentation submitted will be proofread and amended before merging. Please don't take this personally if any of your documentation gets amended; we just want to make sure all documents are ready to go before merging them into master.
Installing the Docs
Firstly, pull this repo into a local area on your machine, navigate to that directory, and run the following command:
$ yarn
Local Development
To start Docusaurus 3 navigate to the folder where the repo resides from a command prompt and issue the following command.
$ yarn start
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
Build
$ yarn build
This command generates static content into the build directory and can be served using any static contents hosting service.
Deployment
Using SSH:
$ USE_SSH=true yarn deploy
Not using SSH:
$ GIT_USER=<Your GitHub username> yarn deploy
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the gh-pages branch.
Writing Good Release Notes
For general guidelines, see Contributing section of the documentation. The Documentation site is not versioned in the same manner as the rest of the project. The Documentation website is more of a living document. Merges into master will have the title and PR# as commit message, with the PR description as extended git commit description.