isolate a malformed card response to the card that caused it
What changed, and why it matters
This commit adds broader error handling when reading hardware cards during wallet import. Previously, an unexpected or malformed response from a card could throw an unhandled exception and potentially crash or disrupt the import process for other cards. The change catches any runtime exception, logs it, and limits the failure to the specific card that caused it. It is a defensive hardening fix rather than a clear-cut vulnerability patch.
Treat as a defensive hardening improvement. Review whether malformed card responses could previously cause denial of service or unexpected UI behavior during hardware wallet import. No immediate emergency response is indicated, but users importing from cards should upgrade to benefit from improved error isolation.
Security signals we found
Addition of broad exception handling around hardware card communication
Commit message references malformed card responses
Inline comment notes that cards can return arbitrary bytes causing runtime exceptions
Prevents a single card failure from affecting card enumeration/import flow
Evidence from the diff
The patch wraps card-reading operations in catch(Exception e) blocks. In CardImportPane.java, a generic catch is added around importCard() so that any runtime exception during card reading is surfaced to the user as a card error without propagating. In Hwi.java, enumerateCard() now catches generic Exceptions per card and logs them, preventing a malformed card response from aborting enumeration of other cards. The commit message and inline comment explicitly frame this as isolating malformed card responses.
Changed components
src/main/java/com/sparrowwallet/sparrow/control/CardImportPane.javasrc/main/java/com/sparrowwallet/sparrow/io/Hwi.javaInspect captured patch +8 / −0
### src/main/java/com/sparrowwallet/sparrow/control/CardImportPane.java
@@ -112,6 +112,11 @@ private void importCard() {
setError("Card Error", e.getMessage());
importButton.setDisable(false);
return;
+ } catch(Exception e) {
+ log.error("Error reading card", e);
+ setError("Card Error", e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage());
+ importButton.setDisable(false);
+ return;
}
CardImportService cardImportService = new CardImportService(importer, policyType, pin.get(), derivation, messageProperty);
### src/main/java/com/sparrowwallet/sparrow/io/Hwi.java
@@ -98,6 +98,9 @@ private List<Device> enumerateCard() {
//ignore
} catch(CardException e) {
log.info("Error reading card", e);
+ } catch(Exception e) {
+ //a card is free to return any bytes it likes, so a malformed response can surface as any runtime exception
+ log.error("Error reading card", e);
}
}
Why this scored 35/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.