fix: escape FinTS control characters in HNSHA/HNSHK/HNVSK segments + CVE-2026-26278#39
Conversation
Passwords or usernames containing FinTS control characters (@ + : ' ?) were serialized raw, causing error 9010 on ING servers. - hnsha.ts: wrap pin and tan with Format.stringEscaped() - hnshk.ts: wrap name with Format.stringEscaped() - hnvsk.ts: wrap name with Format.stringEscaped() - Add serialization tests with @ in pin/tan/name for all three segments - Bump version to 0.9.0 Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/41587821-3c4e-484b-b42f-a2514748f3f0 Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/41587821-3c4e-484b-b42f-a2514748f3f0 Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
|
@copilot resolve the merge conflicts in this pull request |
…re-structure-errors # Conflicts: # yarn.lock Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
Done — merged |
There was a problem hiding this comment.
Pull request overview
This PR fixes outbound FinTS serialization for credentials containing FinTS control characters in security-related segments (HNSHA/HNSHK/HNVSK) and updates fast-xml-parser to address CVE-2026-26278 in fints-lib.
Changes:
- Escape FinTS control characters in
HNSHA.pin/tan,HNSHK.name, andHNVSK.nameusingFormat.stringEscaped(). - Add segment serialization/deserialization test cases covering
@and+escaping. - Bump
fast-xml-parserdependency (and update lockfile) and bumpfints-libversion to0.9.0.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Lockfile updates for dependency bump(s); currently includes absolute-path workspace keys. |
| packages/fints/package.json | Bumps fints-lib version and fast-xml-parser dependency range. |
| packages/fints/src/segments/hnsha.ts | Escapes pin/tan during serialization. |
| packages/fints/src/segments/hnshk.ts | Escapes name during serialization. |
| packages/fints/src/segments/hnvsk.ts | Escapes name during serialization. |
| packages/fints/src/segments/tests/test-hnsha.ts | Adds escaping coverage for PIN/TAN serialization. |
| packages/fints/src/segments/tests/test-hnshk.ts | Adds escaping coverage for name serialization; updates date/time mocking. |
| packages/fints/src/segments/tests/test-hnvsk.ts | Adds escaping + unescaping coverage for name; updates date/time mocking. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| jest.spyOn(Format, "date").mockReturnValue("20180907"); | ||
| jest.spyOn(Format, "time").mockReturnValue("080000"); |
There was a problem hiding this comment.
jest.spyOn(Format, "date/time").mockReturnValue(...) is executed at module load and never restored. Since the package’s Jest config doesn’t enable restoreMocks, these mocks can leak into other test files in the same run. Add an afterAll/afterEach that restores mocks (or scope the spies inside a describe with proper teardown) so other tests aren’t affected.
| jest.spyOn(Format, "date").mockReturnValue("20180907"); | ||
| jest.spyOn(Format, "time").mockReturnValue("080000"); |
There was a problem hiding this comment.
jest.spyOn(Format, "date/time").mockReturnValue(...) is executed at module load and never restored. Since the package’s Jest config doesn’t enable restoreMocks, these mocks can leak into other test files in the same run. Add an afterAll/afterEach that restores mocks (or scope the spies inside a describe with proper teardown) so other tests aren’t affected.
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/1429c688-259b-42e2-bbe0-3089df9a3df8 Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
Done in |
Passwords or usernames containing FinTS control characters (
@,+,:,',?) were serialized raw in three outbound segments. On ING, a PIN likeabc@xyzcauses the server to interpret@xyzas a binary-length prefix inside the HNVSD inner payload → error 9010 / dialog aborted (9800).Escaping fixes
HKIDNalready usedFormat.stringEscaped()correctly; the three affected segments did not:HNSHApin,tanFormat.stringEscaped()HNSHKnameFormat.stringEscaped()HNVSKnameFormat.stringEscaped()Tests
Added serialization round-trip cases to all three test files covering
@and+in the affected fields, e.g.secret@pass→secret?@pass,user@example.com→user?@example.com. HNVSK also exercises deserialization sinceparse()already unescapes?@→@.Dependency
Bumped
fast-xml-parserfrom^5.3.3to^5.5.6to address CVE-2026-26278 (numeric entity expansion bypassing entity expansion limits). The CLI has no direct dependency onfast-xml-parserand picks up the fix transitively throughfints-lib.Version
fints-libbumped0.8.0→0.9.0.