HexBrain

Monero · Report #3749681

Background sync cache retains outgoing additional transaction secret keys

Validstatus
lowseverity
1upvotes
20 Aug 2026disclosed

How it was found

Summary:

Monero wallet background sync is documented as scanning "with just the view key while the wallet is locked." The source also documents wallet2::clear_user_data() as the scrub step intended to remove data not needed by a background wallet with only a hot view key.

In the reviewed source tree, wallet2::store_background_cache() clones the full wallet cache, calls clear_user_data(), and stores the result as the background cache. clear_user_data() clears m_tx_keys, but it does not clear m_additional_tx_keys, even though m_additional_tx_keys is a serialized wallet-cache field containing std::vector<crypto::secret_key> values indexed by transaction hash.

This appears to leave outgoing additional transaction secret keys in the lower-trust background cache encrypted under the background cache key rather than only under the main wallet cache protection.

This is not a spend-key or seed disclosure issue. The theoretical impact is limited to wallet privacy / proof-key material exposure for outgoing transactions that used additional tx keys.

Releases Affected:

  • Reviewed local source tree: src/version.cpp.in declares DEF_MONERO_VERSION "0.18.1.0".
  • Affected OS: likely OS-independent wallet cache logic on Linux, macOS, Windows, and other supported platforms if this code is present.
  • Exact maintained release range was not validated and should be confirmed by maintainers against current supported branches.

Steps To Reproduce:

No exploit, payload, crash trigger, or live-network validation was performed. These are source-code review steps only.

  1. Review wallet2::store_background_cache(): it serializes the current wallet object, deserializes it into a background wallet object, calls background_w2->clear_user_data(), then stores the background cache.
  2. Review wallet2::clear_user_data(): it clears m_tx_keys, notes, destinations, labels, attributes, and related user data, but does not clear m_additional_tx_keys.
  3. Review wallet serialization: m_additional_tx_keys is serialized in the wallet cache.
  4. Review the field definition: m_additional_tx_keys stores std::vector<crypto::secret_key> values.
  5. Review transaction commit/signing paths: outgoing transaction information stores ptx.additional_tx_keys into m_additional_tx_keys when store_tx_info() is enabled, which is the default.
  6. Review proof/check logic: additional tx keys are later used as secret inputs for tx-key checks and tx proofs, showing they are sensitive transaction secret material.

Supporting Material/References:

  • src/wallet/wallet2.cpp:13751 - wallet2::store_background_cache() clones, scrubs, and stores the background cache.
  • src/wallet/wallet2.cpp:4532 - wallet2::clear_user_data() clears m_tx_keys but not m_additional_tx_keys.
  • src/wallet/wallet2.h:1819 - comment explains clear_user_data() exists for background wallet sensitive-data minimization.
  • src/wallet/wallet2.h:1390 - m_additional_tx_keys is serialized into the wallet cache.
  • src/wallet/wallet2.h:1934 - m_additional_tx_keys stores std::vector<crypto::secret_key>.
  • src/wallet/wallet2.cpp:7627 - commit path stores ptx.additional_tx_keys.
  • src/wallet/wallet2.cpp:1200 - m_store_tx_info defaults to true.
  • src/wallet/wallet2.cpp:12088 - additional tx keys are used in tx-key checks.
  • src/wallet/wallet2.cpp:12252 - additional tx keys are used to generate tx proofs.

Why this may be reportable:

The code has an explicit scrub function for background sync data minimization. That scrub clears the primary outgoing transaction secret-key map, m_tx_keys, but misses the adjacent serialized secret-key map, m_additional_tx_keys.

Because background sync can use a custom background password and is described as view-key-only scanning while locked, retaining extra outgoing transaction secret keys in the background cache appears to cross the intended wallet-lock/background-sync trust boundary.

Why this may be a false positive:

Maintainers may consider the background cache password/key sufficient protection for all cached metadata, or may classify additional tx keys as acceptable to retain in the background cache. Also, practical impact requires local access to the background cache and relevant background credentials, and only affects transactions with non-empty additional tx keys.

Suggested remediation:

Clear m_additional_tx_keys in wallet2::clear_user_data() alongside m_tx_keys.

Consider adding a regression test or static serialization assertion that a background cache produced from a wallet containing both m_tx_keys and m_additional_tx_keys retains neither field.

AI Usage Acknowledgement:

This report was prepared with AI assistance for source-code navigation, candidate triage, and drafting. The substantive claim is based on the cited Monero source files. No PoC, exploit code, payload, fuzzing, crash triggering, live-network testing, or reproduction script was created.

Housekeeping

  1. I have reviewed the program policy before submitting.
  2. XMR address: 479Zu6GkFNTfRcNkesCtHNJg37KE72PAG5VLFC1bQNBjLEi2ZqhUByff67M1KsHVpsEs5CBP6YgNwgrJTZRPmbRZUSVvtM6

Impact

A local actor who can access the background wallet cache and its background password/key, but not the main wallet password, may be able to recover outgoing additional transaction secret keys retained in m_additional_tx_keys.

The likely impact is transaction privacy degradation and unintended disclosure of proof-capable outgoing transaction key material for affected transactions. This could help prove or link wallet involvement in specific outgoing payments under some conditions, especially when combined with transaction IDs, recipient addresses, or other wallet/cache metadata.

This does not appear to expose the wallet seed, private spend key, or private view key, and it does not appear to allow spending funds.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original