* [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-2frjhttps://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-L340https://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
* fix github actions inconsistencies
* fix pinning of transitive deps in eslint-plugin
* drop use of node-fetch in api
* drop md5 dependency in favour of node:crypto
* drop slash
* drop unused top level packages
* add note about node-polyfills warning
* remove unused deps from desktop-client
* drop pegjs types
* note
* drop node-jq
* [AI] Publish loot-core (@actual-app/core) nightly first in workflow
* [autofix.ci] apply automated fixes
* Refactor imports and update configuration
- Updated .oxfmtrc.json to change "parent" to ["parent", "subpath"].
- Removed unnecessary blank lines in various TypeScript files to improve code readability.
- Adjusted import order in reports and rules files for consistency.
* Add workflow steps to pack and publish the core package nightly
* Remove nightly tag from npm publish command in workflow for core package
* Update post-build script comment to reflect correct workspace command for loot-core declarations
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* refactor(api): defineConfig vitest, api-helpers, drop vite.api build
- Wrap api vitest.config with defineConfig for typing/IDE
- Add loot-core api-helpers, use in YNAB4/YNAB5 importers
- Remove vite.api.config, build-api, injected.js; simplify api package
* refactor(api): update package structure and build scripts
- Change main entry point and types definition paths in package.json to reflect new structure.
- Simplify build script by removing migration and default database copy commands.
- Adjust tsconfig.dist.json to maintain declaration directory.
- Add typings for external modules in a new typings.ts file.
- Update comments in schedules.ts to improve clarity and maintainability.
* chore(api): update dependencies and build configuration
- Replace tsc-alias with rollup-plugin-visualizer in package.json.
- Update build script to use vite for building the API package.
- Add vite configuration file for improved build process and visualization.
- Adjust tsconfig.dist.json to exclude additional configuration files from the build.
* fix(api): update visualizer output path in vite configuration
- Change the output filename for the visualizer plugin from 'dist/stats.json' to 'app/stats.json' to align with the new directory structure.
* refactor(api): streamline Vite configuration and remove vitest.config.ts
- Remove vitest.config.ts as its configuration is now integrated into vite.config.ts.
- Update vite.config.ts to include sourcemap generation and adjust CRDT path resolution.
- Modify vitest.setup.ts to correct the import path for the CRDT proto file.
* feat(api): enhance build scripts and add file system utilities
- Update build scripts in package.json to include separate commands for building node, migrations, and default database.
- Introduce a new file system utility module in loot-core to handle file operations such as reading, writing, and directory management.
- Implement error handling and logging for file operations to improve robustness.
* Refactor typecheck script in api package and enhance api-helpers with new schedule and rule update functions. The typecheck command was simplified by removing the strict check, and new API methods for creating schedules and updating rules were added to improve functionality.
* Refactor API integration in loot-core by removing api-helpers and directly invoking handlers. Update typecheck script in api package to include strict checks, and refine TypeScript configurations across multiple packages for improved type safety and build processes.
* Refactor imports and enhance code readability across multiple files in loot-core. Simplified import statements in the API and adjusted formatting in YNAB importers for consistency. Updated type annotations to improve type safety and maintainability.
* Refactor handler invocation in YNAB importers to use the new send function from main-app. This change improves code consistency and readability by standardizing the method of invoking handlers across different modules.
* Refactor schedule configuration in loot-core to enhance type safety by introducing a new ScheduleRuleOptions type. This change improves the clarity of the recurring schedule configuration and ensures better type checking for frequency and interval properties.
* Update TypeScript configuration in api package to include path mapping for loot-core. This change enhances module resolution and improves type safety by allowing direct imports from the loot-core source directory.
* Update TypeScript configuration in api package to reposition the typescript-strict-plugin entry. This change improves the organization of the tsconfig.json file while maintaining the existing path mapping for loot-core, ensuring consistent type checking across the project.
* Update TypeScript configurations across multiple packages to enable noEmit option. This change enhances build processes by preventing unnecessary output files during compilation. Additionally, remove the obsolete tsconfig.api.json file from loot-core to streamline project structure.
* Update TypeScript configuration in sync-server package to enable noEmit option. This change allows for the generation of output files during compilation, facilitating the build process.
* Update api package configuration to streamline build process and enhance type safety. Removed unnecessary build scripts, integrated vite-plugin-dts for type declaration generation, and added migration and default database copying functionality. Adjusted vitest setup to comment out CRDT proto file import for improved test isolation.
* Update TypeScript configurations in desktop-client and desktop-electron packages to enable noEmit option, allowing for output file generation during compilation. Additionally, add ts-strict-ignore comments in YNAB importers to suppress strict type checking, improving compatibility with embedded API usage.
* Refactor api package configuration to update type declaration paths and enhance build process. Changed type definitions reference in package.json, streamlined tsconfig.json exclusions, and added functionality to copy inlined types during the build. Removed obsolete vitest setup file for improved test isolation.
* Revert to solution without types
* Update TypeScript configuration in API package to use ES2022 module and bundler resolution. This change enhances compatibility with modern JavaScript features and improves the build process.
* Update yarn.lock and API package to enhance TypeScript build process and add new dependencies
* Refactor inline-loot-core-types script to streamline TypeScript declaration handling and improve output organization. Remove legacy code and directly copy loot-core declaration tree, updating index.d.ts to reference local imports.
* Add internal export to API and enhance Vite configuration for migration handling
* Update Vite configuration in API package to target Node 18, enhancing compatibility with the latest Node features.
* Enhance inline-loot-core-types script to improve TypeScript declaration handling by separating source and typings directories. Update the copy process to include emitted typings, ensuring no declarations are dropped and maintaining better organization of loot-core types.
* Enhance migration handling by allowing both .sql and .js files to be copied during the migration process. Refactor file system operations in loot-core to improve error handling and streamline file management, including new methods for reading, writing, and removing files and directories.
* Refactor rootPath determination in Electron file system module by removing legacy case for 'bundle.api.js'. This simplifies the path management for the Electron app.
* Update API tests to mock file system paths for migration handling and change Vite configuration to target Node 20 for improved compatibility.
* Add promise-retry dependency to loot-core package and update yarn.lock
* Fix lint
* Refactor build script order in package.json for improved execution flow
* Feedback: API changes for "internal"
* Update linting rules and replace @ts-ignore with @ts-expect-error
* Add release notes for PR #6636
* Fix TypeScript linting issue by adding @ts-ignore for electron types in server start message
* Change category to Maintenance and update linting rules
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Bundle loot-core types into the API
So we can have loot-core be the source of truth
for some types that get passed through
- Improves downstream development with API by including types
- Use path aliases for dist vs dev tsconfigs
- Convert api index to typescript as example
- Permit ts-ignore for issues with our version of typescript
---------
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>