Clear the passphrase status when returning
What changed, and why it matters
This commit adds code that clears the optional passphrase text from the screen and resets its visibility to hidden (password mode) whenever the user navigates back from passphrase entry during wallet creation, import, or settings. It also refactors how the 'show/hide' eye icon is controlled. The change looks like a cleanup fix to prevent a sensitive passphrase from lingering on screen or staying visible after a user leaves the page, which could reduce the risk of shoulder-surfing or accidental disclosure.
Treat as a defensive UI-hygiene improvement rather than an urgent vulnerability. If auditing, verify that all navigation paths that leave passphrase entry call GuiPassphraseWidgetClearText(), that the text is also cleared from any underlying model/state (not just the LVGL textarea), and that the passphrase is never logged or retained in memory longer than necessary.
Security signals we found
Sensitive UI state (passphrase text and visibility) is explicitly cleared on navigation back
Refactored password-mode toggle to allow programmatic reset to hidden
No input validation, buffer handling, or cryptographic code was modified
No mention of CVE, bug bounty, or security advisory in commit metadata
Evidence from the diff
The patch introduces GuiPassphraseWidgetClearText(), which empties both passphrase textareas, forces them back into password mode (hidden text), resets focus to the first field, and re-targets the on-screen keyboard. It calls this function on PrevTile navigation in create-share, import-phrase, import-share, and single-phrase flows. Additionally, it extracts SwitchPasswordMode() from the event handler so it can be reused programmatically, and stores the eye-image objects in the passphrase widget struct. No cryptographic or storage-layer changes are present.
Changed components
Passphrase entry UI widgetWallet creation (share) flowWallet import phrase flowWallet import share flowSingle phrase backup flowPassphrase settings UIInspect captured patch +30 / −6
diff --git a/src/ui/gui_widgets/gui_create_share_widgets.c b/src/ui/gui_widgets/gui_create_share_widgets.c
index 7edd16e..6d5532f 100644
--- a/src/ui/gui_widgets/gui_create_share_widgets.c
+++ b/src/ui/gui_widgets/gui_create_share_widgets.c
@@ -519,6 +519,7 @@ int8_t GuiCreateSharePrevTile(void)
SetNavBarMidBtn(g_pageWidget->navBarWidget, NVS_MID_BUTTON_BUTT, NULL, NULL);
SetNavBarLeftBtn(g_pageWidget->navBarWidget, NVS_BAR_CLOSE, StopCreateViewHandler, NULL);
SetNavBarRightBtn(g_pageWidget->navBarWidget, NVS_BAR_WORD_RESET, ResetBtnHandler, NULL);
+ GuiPassphraseWidgetClearText();
break;
}
diff --git a/src/ui/gui_widgets/gui_enter_passcode.c b/src/ui/gui_widgets/gui_enter_passcode.c
index 64b682b..11230df 100644
--- a/src/ui/gui_widgets/gui_enter_passcode.c
+++ b/src/ui/gui_widgets/gui_enter_passcode.c
@@ -738,17 +738,18 @@ void GuiFingerPrintStatus(GuiEnterPasscodeItem_t *item, bool en, uint8_t errCnt)
}
}
+void SwitchPasswordMode(lv_obj_t *ta, lv_obj_t *img, bool isPassword)
+{
+ lv_textarea_set_password_mode(ta, isPassword);
+ lv_img_set_src(img, isPassword ? &imgEyeOff : &imgEyeOn);
+}
+
void SwitchPasswordModeHandler(lv_event_t *e)
{
lv_obj_t *ta = lv_event_get_user_data(e);
lv_obj_t *img = lv_event_get_target(e);
bool en = lv_textarea_get_password_mode(ta);
- lv_textarea_set_password_mode(ta, !en);
- if (en) {
- lv_img_set_src(img, &imgEyeOn);
- } else {
- lv_img_set_src(img, &imgEyeOff);
- }
+ SwitchPasswordMode(ta, img, !en);
}
const int8_t MAX_SCORE = 90; // MAX SCORE = 25 + 10 + 10 + 20 + 25 = 90
diff --git a/src/ui/gui_widgets/gui_enter_passcode.h b/src/ui/gui_widgets/gui_enter_passcode.h
index 62bdbce..aa9ebc0 100644
--- a/src/ui/gui_widgets/gui_enter_passcode.h
+++ b/src/ui/gui_widgets/gui_enter_passcode.h
@@ -52,6 +52,7 @@ void PassWordPinSwitch(GuiEnterPasscodeItem_t *item);
void GuiEnterPassLabelRefresh(void);
void GuiShuffleNumKeyBoardMap(GuiEnterPasscodeItem_t *item);
void GuiSetNumKeyBoardMapDefault(GuiEnterPasscodeItem_t *item);
+void SwitchPasswordMode(lv_obj_t *ta, lv_obj_t *img, bool isPassword);
#endif /* _GUI_ENTER_PASSCODE_H */
diff --git a/src/ui/gui_widgets/gui_import_phrase_widgets.c b/src/ui/gui_widgets/gui_import_phrase_widgets.c
index 012de7f..bc9f3c7 100644
--- a/src/ui/gui_widgets/gui_import_phrase_widgets.c
+++ b/src/ui/gui_widgets/gui_import_phrase_widgets.c
@@ -186,6 +186,7 @@ int8_t GuiImportPhrasePrevTile(void)
GuiCloseCurrentWorkingView();
break;
case SINGLE_PHRASE_PASSPHRASE:
+ GuiPassphraseWidgetClearText();
if (g_buttonCont != NULL) lv_obj_clear_flag(g_buttonCont, LV_OBJ_FLAG_HIDDEN);
SetRightBtnLabel(g_pageWidget->navBarWidget, NVS_BAR_WORD_RESET, _("import_wallet_phrase_clear_btn"));
SetRightBtnCb(g_pageWidget->navBarWidget, ResetClearImportHandler, NULL);
diff --git a/src/ui/gui_widgets/gui_import_share_widgets.c b/src/ui/gui_widgets/gui_import_share_widgets.c
index 865e3ee..25d00cd 100644
--- a/src/ui/gui_widgets/gui_import_share_widgets.c
+++ b/src/ui/gui_widgets/gui_import_share_widgets.c
@@ -210,6 +210,7 @@ int8_t GuiImportSharePrevTile(void)
case IMPORT_SHARE_WRITE_SE:
break;
case IMPORT_SHARE_PASSPHRASE:
+ GuiPassphraseWidgetClearText();
SetNavBarLeftBtn(g_pageWidget->navBarWidget, NVS_BAR_CLOSE, StopCreateViewHandler, NULL);
SetNavBarMidBtn(g_pageWidget->navBarWidget, NVS_MID_BUTTON_BUTT, NULL, NULL);
SetRightBtnLabel(g_pageWidget->navBarWidget, NVS_BAR_WORD_RESET, _("import_wallet_phrase_clear_btn"));
diff --git a/src/ui/gui_widgets/gui_single_phrase_widgets.c b/src/ui/gui_widgets/gui_single_phrase_widgets.c
index ac9e8cc..ece7c6d 100644
--- a/src/ui/gui_widgets/gui_single_phrase_widgets.c
+++ b/src/ui/gui_widgets/gui_single_phrase_widgets.c
@@ -445,6 +445,7 @@ int8_t GuiSinglePhrasePrevTile(void)
SetNavBarMidBtn(g_pageWidget->navBarWidget, NVS_MID_BUTTON_BUTT, NULL, NULL);
SetRightBtnLabel(g_pageWidget->navBarWidget, NVS_BAR_WORD_RESET, _("single_phrase_reset"));
SetRightBtnCb(g_pageWidget->navBarWidget, ResetBtnHandler, NULL);
+ GuiPassphraseWidgetClearText();
ResetConfirmInput();
break;
}
diff --git a/src/ui/gui_widgets/setting/gui_passphrase_setting_widgets.c b/src/ui/gui_widgets/setting/gui_passphrase_setting_widgets.c
index 0294f4b..98883d3 100644
--- a/src/ui/gui_widgets/setting/gui_passphrase_setting_widgets.c
+++ b/src/ui/gui_widgets/setting/gui_passphrase_setting_widgets.c
@@ -26,6 +26,8 @@
typedef struct PassphraseWidget {
lv_obj_t *inputTa;
lv_obj_t *repeatTa;
+ lv_obj_t *inputEyeImg;
+ lv_obj_t *repeatEyeImg;
lv_obj_t *errLabel;
lv_obj_t *lenOverLabel;
} PassphraseWidget_t;
@@ -128,6 +130,7 @@ void GuiWalletPassphraseEnter(lv_obj_t *parent, bool needVerify)
lv_obj_align(img, LV_ALIGN_DEFAULT, 411, 168 - GUI_MAIN_AREA_OFFSET);
lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(img, SwitchPasswordModeHandler, LV_EVENT_CLICKED, ta);
+ g_passphraseWidget.inputEyeImg = img;
lv_textarea_set_max_length(ta, PASSWORD_MAX_LEN);
lv_textarea_set_one_line(ta, true);
lv_obj_set_scrollbar_mode(ta, LV_SCROLLBAR_MODE_OFF);
@@ -159,6 +162,7 @@ void GuiWalletPassphraseEnter(lv_obj_t *parent, bool needVerify)
lv_obj_align(img, LV_ALIGN_DEFAULT, 411, 252 - GUI_MAIN_AREA_OFFSET);
lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(img, SwitchPasswordModeHandler, LV_EVENT_CLICKED, repeatTa);
+ g_passphraseWidget.repeatEyeImg = img;
g_passphraseWidget.repeatTa = repeatTa;
g_setPassPhraseKb = GuiCreateFullKeyBoard(parent, UpdatePassPhraseHandler, KEY_STONE_FULL_L, NULL);
@@ -292,4 +296,17 @@ static void UpdatePassPhraseHandler(lv_event_t *e)
}
}
}
+}
+
+void GuiPassphraseWidgetClearText(void)
+{
+ lv_textarea_set_text(g_passphraseWidget.inputTa, "");
+ lv_textarea_set_text(g_passphraseWidget.repeatTa, "");
+ SwitchPasswordMode(g_passphraseWidget.inputTa, g_passphraseWidget.inputEyeImg, true);
+ SwitchPasswordMode(g_passphraseWidget.repeatTa, g_passphraseWidget.repeatEyeImg, true);
+ lv_obj_add_state(g_passphraseWidget.inputTa, LV_STATE_FOCUSED);
+ lv_obj_clear_state(g_passphraseWidget.repeatTa, LV_STATE_FOCUSED);
+ if (g_setPassPhraseKb != NULL) {
+ lv_keyboard_set_textarea(g_setPassPhraseKb->kb, g_passphraseWidget.inputTa);
+ }
}
\ No newline at end of file
diff --git a/src/ui/gui_widgets/setting/gui_setting_widgets.h b/src/ui/gui_widgets/setting/gui_setting_widgets.h
index 4836400..a5c66ba 100644
--- a/src/ui/gui_widgets/setting/gui_setting_widgets.h
+++ b/src/ui/gui_widgets/setting/gui_setting_widgets.h
@@ -168,6 +168,7 @@ void GuiWalletPassphrase(lv_obj_t *parent);
void GuiWalletPassphraseEnter(lv_obj_t *parent, bool needVerify);
void OpenPassphraseTutorialHandler(lv_event_t *e);
bool GuiPassphraseQuickAccess(void);
+void GuiPassphraseWidgetClearText(void);
// seed check
void GuiWalletRecoveryMethodCheck(lv_obj_t *parent);
Why this scored 47/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.