keepassxc icon indicating copy to clipboard operation
keepassxc copied to clipboard

No check for duplicate group UUID causes crash

Open droidmonkey opened this issue 3 months ago • 0 comments

Summary

A malformed KDBX file can reuse an ancestor’s UUID to create parent/child group cycles, causing the KeePassXC GUI to hang when the victim selects the attacker-controlled group (default build, no special config).

Details

KdbxXmlReader::parseGroup() reuses the first-seen UUID via getGroup(uuid) and then attaches children with child->setParent(group) without validating ancestry (src/format/KdbxXmlReader.cpp:596-626, 1168-1192).

Group::setParent() only asserts this != parent in debug and never checks ancestors for cycles (src/core/Group.cpp:461-514), so duplicate ancestor UUIDs create A→B→A loops in release builds.

UI paths assume parent chains terminate, e.g., entry->group()->fullPath() (src/gui/entry/EntryModel.cpp:139-142) and group->isRecycled() (src/gui/DatabaseWidget.cpp:2715-2729, invoked from src/gui/MainWindow.cpp:937); traversal on a cyclic group loops indefinitely on the UI thread.

PoC

  1. Export any valid KDBX to XML.
  2. In the XML, set an inner <Group>’s UUID to match one of its ancestor groups (keep nested structure).
  3. Repack/import and open in stock KeePassXC.
  4. Click the malicious group (or an entry within it). The UI becomes unresponsive (infinite loop/recursion).

Originally reported by @0xkato

droidmonkey avatar Nov 22 '25 18:11 droidmonkey