@@ -309,11 +309,18 @@ bool MnemonicVerificationDialog::validateWord(const QString& word, int position)
309309 // Parse words on-demand for validation (minimizes exposure time)
310310 // Words are kept in memory during step 2 (verification) and step 1 (when revealed)
311311 // They are only cleared when explicitly hiding in step 1 or on dialog destruction
312- QStringList words = parseWords ();
313- if (position < 1 || position > words.size ()) {
312+ std::vector<SecureString> words = parseWords ();
313+ if (position < 1 || position > static_cast < int >( words.size () )) {
314314 return false ;
315315 }
316- return word == words[position - 1 ].toLower ();
316+ // Convert SecureString to QString temporarily for comparison
317+ QString secureWord = QString::fromStdString (std::string (words[position - 1 ].begin (), words[position - 1 ].end ()));
318+ bool result = word == secureWord.toLower ();
319+ // Clear temporary QString immediately
320+ secureWord.fill (QChar (0 ));
321+ secureWord.clear ();
322+ secureWord.squeeze ();
323+ return result;
317324}
318325
319326void MnemonicVerificationDialog::updateWordValidation ()
@@ -364,47 +371,61 @@ void MnemonicVerificationDialog::clearMnemonic()
364371 m_mnemonic.assign (m_mnemonic.size (), 0 );
365372}
366373
367- QStringList MnemonicVerificationDialog::parseWords ()
374+ std::vector<SecureString> MnemonicVerificationDialog::parseWords ()
368375{
369376 // If words are already parsed, reuse them (for step 2 validation or step 1 display)
370- if (!m_words.isEmpty ()) {
377+ if (!m_words.empty ()) {
371378 return m_words;
372379 }
373380
374381 // Parse words from secure mnemonic string
375382 QString mnemonicStr = QString::fromStdString (std::string (m_mnemonic.begin (), m_mnemonic.end ()));
376- m_words = mnemonicStr.split (QRegularExpression (" \\ s+" ), Qt::SkipEmptyParts);
383+ QStringList wordList = mnemonicStr.split (QRegularExpression (" \\ s+" ), Qt::SkipEmptyParts);
384+
385+ // Convert to SecureString vector for secure storage
386+ m_words.clear ();
387+ m_words.reserve (wordList.size ());
388+ for (const QString& word : wordList) {
389+ std::string wordStd = word.toStdString ();
390+ SecureString secureWord;
391+ secureWord.assign (std::string_view{wordStd});
392+ m_words.push_back (secureWord);
393+ // Clear temporary std::string
394+ wordStd.assign (wordStd.size (), 0 );
395+ }
377396
378397 // Clear the temporary QString immediately after parsing
398+ mnemonicStr.fill (QChar (0 ));
379399 mnemonicStr.clear ();
380400 mnemonicStr.squeeze (); // Release memory
401+ wordList.clear ();
381402
382403 return m_words;
383404}
384405
385406void MnemonicVerificationDialog::clearWordsSecurely ()
386407{
387408 // Securely clear each word string by overwriting before clearing
388- for (QString & word : m_words) {
409+ for (SecureString & word : m_words) {
389410 // Overwrite with zeros before clearing
390- word.fill ( QChar ( 0 ) );
411+ word.assign (word. size (), 0 );
391412 word.clear ();
392- word.squeeze (); // Release memory
393413 }
394414 m_words.clear ();
395415}
396416
397417int MnemonicVerificationDialog::getWordCount () const
398418{
399- // Count words without parsing them into QStringList
419+ // Count words without parsing them into vector
400420 // This avoids storing words in non-secure memory unnecessarily
401- if (m_words.isEmpty ()) {
421+ if (m_words.empty ()) {
402422 QString mnemonicStr = QString::fromStdString (std::string (m_mnemonic.begin (), m_mnemonic.end ()));
403423 QStringList words = mnemonicStr.split (QRegularExpression (" \\ s+" ), Qt::SkipEmptyParts);
404424 int count = words.size ();
405425 // Clear immediately
406426 mnemonicStr.clear ();
407427 mnemonicStr.squeeze ();
428+ words.clear ();
408429 return count;
409430 }
410431 return m_words.size ();
@@ -421,7 +442,7 @@ void MnemonicVerificationDialog::buildMnemonicGrid(bool reveal)
421442 }
422443
423444 // Parse words only when revealing (when needed for display)
424- QStringList words;
445+ std::vector<SecureString> words;
425446 if (reveal) {
426447 words = parseWords ();
427448 } else {
@@ -462,10 +483,16 @@ void MnemonicVerificationDialog::buildMnemonicGrid(bool reveal)
462483 for (int r = 0 ; r < rows; ++r) {
463484 for (int c = 0 ; c < columns; ++c) {
464485 int idx = r * columns + c; if (idx >= n) break ;
465- const QString text = QString (" %1. %2" ).arg (idx + 1 , 2 ).arg (words[idx]);
486+ // Convert SecureString to QString temporarily for display
487+ QString wordStr = QString::fromStdString (std::string (words[idx].begin (), words[idx].end ()));
488+ const QString text = QString (" %1. %2" ).arg (idx + 1 , 2 ).arg (wordStr);
466489 QLabel* lbl = new QLabel (text);
467490 lbl->setTextInteractionFlags (Qt::TextSelectableByMouse);
468491 m_gridLayout->addWidget (lbl, r, c);
492+ // Clear temporary QString immediately after use
493+ wordStr.fill (QChar (0 ));
494+ wordStr.clear ();
495+ wordStr.squeeze ();
469496 }
470497 }
471498
0 commit comments